WPF や Silverlight では、XAML で UI を記述するのが基本です。でも、どうしてもコードで記述せざるを得ない場合がまれにあります。たとえば、配置する要素がユーザーの設定内容で変わる場合とか。
だいぶ前に、C# のコードで XAML っぽく記述できる DSL を作ってみました。
でも、このような DSL を実装するのはひと苦労。もっと簡単な方法がいいですよね。例えば、オブジェクト初期化子とコレクション初期子を駆使すれば、XAML っぽく書けるのでは?
やってみました。
using System; using System.Windows; using System.Windows.Controls; namespace CreateElementSample { /// <summary> /// MainWindow.xaml の相互作用ロジック /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); // オブジェクト初期化子とコレクション初期化子を駆使して // XAML っぽく UI を構築する Content = new Grid() { RowDefinitions = { new RowDefinition() { Height = GridLength.Auto, }, new RowDefinition() { Height = new GridLength(1.0, GridUnitType.Star) } }, Children = { CreateElement(()=> { var stackPanel = new StackPanel() { Orientation = Orientation.Horizontal, Children = { new TextBox() { Width = 100, }, new Button() { Content = "Test", }, } }; Grid.SetRow(stackPanel, 0); return stackPanel; }), CreateElement(()=> { var dataGrid = new DataGrid() { Columns = { new DataGridTextColumn() { Header = "ID", }, new DataGridTextColumn() { Header = "Name", }, } }; Grid.SetRow(dataGrid, 1); return dataGrid; }), }, }; } // 添付プロパティを設定するときに使うメソッド private T CreateElement<T>(Func<T> method) { return method(); } } }
添付プロパティはオブジェクト初期化子で設定できないので、ヘルパーメソッドを使って回避しました。要素の記述が XAML みたいに入れ子になっているから、親子関係がわかりやすいんじゃないでしょうか。