かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

コレクション初期化子に渡すオブジェクトをデリゲートを使って組み立てたい

よくわからないタイトルになってしまいましたが、Xamarin.Forms使おうとして出てきた問題です。

Xamarin.Formsは、現時点ではXAMLのデザイナとか提供されてないので、長い目で見るとXAMLで書いておいたほうがいいのは確かなんですが、勉強するためにインテリセンスがないのはちょいと辛い。なので、勉強するときはC#で軽く組んでおいて感覚をつかんでから、デザイナが出てきたらXAMLに乗り換えるといったことを目論んでいます。

そんなときに、Gridにボタンを置いたり、Bindingを設定したオブジェクトを配置したりといったことをしようとすると、以下のように一度変数に入れて書いたりしてました。めんどい。

// 初期化と
Button b = new Button { Text = "Hello" };
Grid.SetRow(b, 1);
Grid.SetColumn(b, 1);
b.SetBinding(Button.CommandProperty, "Hoge");

Content = new Grid
{
    RowDefinitions = { new RowDefinition { Height = GridLength.Auto }, ... },
    Children = 
    {
        b // 配置が分離してしまうよぉぉぉ
    }
};

変数ができてしまうのが気に食わなかったり、めんどくさいと思ってました。

デリゲート使って解決?

こんな風にかけることに気付きました。

Content = new Grid
{
    RowDefinitions = { ...省略... },
    Children =
    {
        new Func<Button>(() =>
        {
            // 配置と初期化処理が同じところにかけるし無駄に変数が増えない!
            var b = new Button { Text = "Hello" };
            Grid.SetRow(b, 1);
            Grid.SetColumn(b, 1);
            b.SetBinding(Button.CommandProperty, "Hoge");
            return b;
        }).Invoke()
    }
};

よりXAMLに近いイメージで書けそう。