読者です 読者をやめる 読者になる 読者になる

だるろぐ

とてもだるだるした日記です http://about.daruyanagi.jp/

お知らせ

失敗の数だけ強くなりたい

C# WPF

f:id:daruyanagi:20120724200928p:plain

朝起きてボーっとしてたんだけど、そしたらふと「Windows Phone端末使って Gist でメモ取れたら便利じゃね?」と思いついた。早速、 Visual Studio を起動。けれど、趣味プログラマーの悲しさ、久しぶりだと何もかもすっかり忘れている*1。しかも、 Silverlight だといろいろ機能が欠けてて面倒くさいことも判明。とりあえず、 WPF で試作品でも作ることにした。 OAuth は面倒そうだったので、それも後回し。まずは Public の Gist を取得して ListBox に並べるところから始めよう。

MainWindow.xaml

<Grid>
    <ListBox Name="listBoxGists">
    </ListBox>
</Grid>

MainWindow.xaml.cs

using System.Net;
using Newtonsoft.Json;

/// <summary>
/// MainWindow.xaml の相互作用ロジック
/// </summary>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }
    
    private void MainWindow_Loaded(
        object sender, RoutedEventArgs e)
    {
        var client = new WebClient();
    
        client.DownloadStringCompleted += (_sender, _e) =>
        {
            listBoxGists.ItemsSource = JsonConvert
                .DeserializeObject<Gist[]>(_e.Result);
        };
    
        client.DownloadStringAsync(
            new Uri("https://api.github.com/gists"));
    }
}

public struct Gist
{
    public string html_url;
    public string git_push_url;
    public User user;
    public string description;
    public int comments;
    public bool @public;
    public Dictionary<string, File> files;
    public string created_at;
    public string url;
    public string id;
    public string updated_at;
    public string git_pull_url;
}

public struct User
{
    public string avatar_url;
    public string gravatar_id;
    public string login;
    public string url;
    public string id;
}

public struct File
{
    public string @type;
    public string filename;
    public string raw_url;
    public string language;
    public string size;
}

これは酷いベタ書きでござる*2。見る人が見たら殴りにくるよね?

第一の失敗

初回ビルドは成功。しかも、ちゃんと動いているみたいだ。けれど、数分後にもう一度試すと例外が発生するようになった。なぜだ。

f:id:daruyanagi:20120724194531p:plain

けれど、これは比較的簡単に原因がわかった。エラーがでた箇所の JSON をみてみる。

f:id:daruyanagi:20120724194701p:plain

日本語がうまく処理されていないらしい。ちゃんと WebClient のエンコードを指定していなかった……

var client = new WebClient()
{
    Encoding = System.Text.UTF8Encoding.UTF8
};

日本語のデータが含まれていても、例外が出なくなった。うまくいった。

第二の失敗

気をよくしたので、ついでに ListBox の見た目をもう少しよくしようと思った。

<Grid>
    <ListBox Name="listBoxGists">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBlock Text="{Binding description}"/>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

f:id:daruyanagi:20120724195003p:plain

うまくいかないでござる! うまくいかないでござる!

System.Windows.Data Error: 40 : BindingExpression path error: 'description' property not found on 'object' ''Gist' (HashCode=284350719)'. BindingExpression:Path=description; DataItem='Gist' (HashCode=284350719); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')

などというエラーがたくさんでている。ここで1時間が経過してタイムオーバー。さすがにもう会社へ行かなくてはいけない。

しかし、会社の椅子に座った途端、ふと気がついた。もしかしたら……!

家に帰って早速コードを一行だけ変更。

public struct Gist
{
    public string html_url;
    public string git_push_url;
    public User user;
    public string description { get; set; } /* Here! */
    public int comments;
    public bool @public;
    public Dictionary<string, File> files;
    public string created_at;
    public string url;
    public string id;
    public string updated_at;
    public string git_pull_url;
}

f:id:daruyanagi:20120724195343p:plain

お見事! フィールドはバインディングできないのでした。

しかし、なんでこんなところで躓いているんだろう……まったく、わたくしさまの人生そのものですな。

*1:歳もとったし

*2:意外なことに、ここまではぐぐることもなく、案外すんなり書けたんだよ!