トップ回答者
TabControl.ContentTemplate内のDataGridのカラム手動設定タイミングについて

質問
-
れいじと申します。
VS2013,C# WPFで開発しております。
下記のコードの場合に、初期化時(ウィンドウ表示時)にDataGridのカラムを手動設定したいのですが、
どのタイミング?イベントで実施すればいいかがわかりません。ご教示いただけないでしょうか。
XAML
<Window x:Class="TabGridTest.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Width="525" Height="350" ContentRendered="MainWindow_OnContentRendered" Loaded="MainWindow_OnLoaded"> <Grid x:Name="layoutRoot"> <TabControl x:Name="testTabControl" ItemsSource="{Binding Path=TestTabItems}" SelectionChanged="TestTabControl_OnSelectionChanged"> <TabControl.ItemTemplate> <DataTemplate> <StackPanel> <TextBlock Text="{Binding Path=TabName}" /> </StackPanel> </DataTemplate> </TabControl.ItemTemplate> <TabControl.ContentTemplate> <DataTemplate> <DataGrid x:Name="testDataGrid" AutoGenerateColumns="False" ItemsSource="{Binding Path=StoreItems}" /> </DataTemplate> </TabControl.ContentTemplate> </TabControl> </Grid> </Window>
CS
using System; using System.Collections.ObjectModel; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Media; namespace TabGridTest { public partial class MainWindow : Window { private MainWindowViewModel mainWindowViewModel { get; set; } public MainWindow() { InitializeComponent(); this.mainWindowViewModel = new MainWindowViewModel(); this.DataContext = this.mainWindowViewModel; } private void MainWindow_OnContentRendered(object sender, EventArgs e) { this.testTabControl.SelectedIndex = 0; // FindVisualChildByNameでNullが返ってしまう this.InitializeTestDataGrid(); } private void MainWindow_OnLoaded(object sender, RoutedEventArgs e) { // FindVisualChildByNameでNullが返ってしまう this.InitializeTestDataGrid(); } private void TestTabControl_OnSelectionChanged(object sender, SelectionChangedEventArgs e) { // ここではFindVisualChildByNameでDataGridが取得できるのでカラムの設定が可能 this.InitializeTestDataGrid(); } private void InitializeTestDataGrid() { DataGrid dataGrid = this.FindVisualChildByName<DataGrid>(this.testTabControl, "testDataGrid"); if (dataGrid == null) return; TestTabItem testTabItem = this.testTabControl.SelectedItem as TestTabItem; if (testTabItem == null) return; // カラム削除 dataGrid.Columns.Clear(); // 各タブごとに表示するカラムや順序が違うため foreach (var dispColumn in testTabItem.DispColumns) { dataGrid.Columns.Add(new DataGridTextColumn() { Header = dispColumn.Name, Binding = new Binding(dispColumn.Key) }); } } // 指定された名前のコントロールを返す private T FindVisualChildByName<T>(DependencyObject parent, string name) where T : FrameworkElement { T child = default(T); for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++) { var ch = VisualTreeHelper.GetChild(parent, i); child = ch as T; if (child != null && child.Name == name) break; else child = FindVisualChildByName<T>(ch, name); if (child != null) break; } return child; } } public class MainWindowViewModel { // タブ一覧 public ObservableCollection<TestTabItem> TestTabItems { get; set; } public MainWindowViewModel() { this.TestTabItems = new ObservableCollection<TestTabItem> { new TestTabItem { TabId = 1, TabName = "Tab1", StoreItems = new ObservableCollection<StoreItem> { new StoreItem { Id = 1, Name = "お店1", Category = "中華", ZipCode = "001", Address = "東京", }, new StoreItem { Id = 2, Name = "お店2", Category = "フレンチ", ZipCode = "002", Address = "札幌", }, new StoreItem { Id = 3, Name = "お店3", Category = "イタリアン", ZipCode = "003", Address = "大阪", }, }, DispColumns = new ObservableCollection<DispColumn> { new DispColumn { Key = "Name", Name = "店名" }, new DispColumn { Key = "Address", Name = "住所" } } }, new TestTabItem { TabId = 2, TabName = "Tab2", StoreItems = new ObservableCollection<StoreItem> { new StoreItem { Id = 1, Name = "居酒屋タロウ", Category = "居酒屋", ZipCode = "001", Address = "東京", }, new StoreItem { Id = 2, Name = "居酒屋ジロウ", Category = "居酒屋", ZipCode = "002", Address = "札幌", }, new StoreItem { Id = 3, Name = "居酒屋サブロウ", Category = "居酒屋", ZipCode = "003", Address = "大阪", }, }, DispColumns = new ObservableCollection<DispColumn> { new DispColumn { Key = "Category", Name = "分類" }, new DispColumn { Key = "Address", Name = "住所" }, new DispColumn { Key = "Name", Name = "店名" }, } } }; } } // タブ用データ public class TestTabItem { public int TabId { get; set; } public string TabName { get; set; } // タブ内のグリッド表示用データ public ObservableCollection<StoreItem> StoreItems { get; set; } // グリッドに表示するカラムデータ public ObservableCollection<DispColumn> DispColumns { get; set; } } // 表示用データ public class StoreItem { public int Id { get; set; } public string Name { get; set; } public string Category { get; set; } public string ZipCode { get; set; } public string Address { get; set; } } // 表示カラム public class DispColumn { public string Key { get; set; } public string Name { get; set; } } }