none
TabControl.ContentTemplate内のDataGridのカラム手動設定タイミングについて RRS feed

  • 質問

  • れいじと申します。

    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; }
        }
    }
    

    2015年8月7日 4:29

回答

  • ベストかどうかはわかりませんが、DataGridのLoadedイベントでは? DataGridに対する設定ですから、DataGridのイベントハンドラで処理した方が良いように思います。

    ★良い回答には回答済みマークを付けよう! MVP - .NET  http://d.hatena.ne.jp/trapemiya/

    • 回答としてマーク れいじ 2015年8月7日 7:46
    2015年8月7日 4:50
    モデレータ

すべての返信

  • ベストかどうかはわかりませんが、DataGridのLoadedイベントでは? DataGridに対する設定ですから、DataGridのイベントハンドラで処理した方が良いように思います。

    ★良い回答には回答済みマークを付けよう! MVP - .NET  http://d.hatena.ne.jp/trapemiya/

    • 回答としてマーク れいじ 2015年8月7日 7:46
    2015年8月7日 4:50
    モデレータ
  • >trapemiya さん

    返信ありがとうございます。

    上手くいきそうです!

    2015年8月7日 7:48