かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

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

よくわからないタイトルになってしまいましたが、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に近いイメージで書けそう。