【问题标题】:TabControl SelectedContent not returning the current selected TabItem contentTabControl SelectedContent 未返回当前选定的 TabItem 内容
【发布时间】:2018-09-12 15:05:45
【问题描述】:

目前我有一个带有多个 TabItem 的 TabControl。每个 TabItem 内部都有一个 DataGrid。我想一次性格式化这些 DataGrid(单元格颜色、列宽等),但我发现我做不到,因为隐藏选项卡中的所有 DataGrid 都会返回 null 属性。在这种情况下,我尝试解决在格式化 DataGrid 之前以编程方式(或使用鼠标手动)选择选项卡的方法。但现在我遇到了一种“奇怪”的行为:

    private void LeftTabs_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    Console.WriteLine(LeftTabs.SelectedIndex);
    var currentDataGrid = (DataGrid)LeftTabs.SelectedContent;
    Console.WriteLine(currentDataGrid.Name);
}

选择的索引返回正确的标签索引,但它的内容没有更新。 假设选择了 Tab 1,然后单击 Tab 2。它返回 Tab 2 索引和 Tab 1 DataGrid 名称。

这种行为使我无法编辑选择选项卡的 DataGrid,因为即使我尝试通过它的对象直接访问它,所有属性都返回 null。

这是 TabControl、item 和 DataGrids XAML 代码:

<TabControl Name="LeftTabs" Margin="0,0,0,0"  Grid.Column="0" Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" SelectionChanged="LeftTabs_SelectionChanged">
        <TabItem>
            <TabItem.Header>Conditions</TabItem.Header>
            <DataGrid x:Name="DataGrid_Conditions" SelectedCellsChanged="DataGrid_Conditions_SelectedCellsChanged" ColumnWidth="80" ItemsSource="{Binding}" HorizontalAlignment="Stretch"   VerticalAlignment="Top" SelectionChanged="ConditionsSelected" />
        </TabItem>
        <TabItem>
            <TabItem.Header>Signals</TabItem.Header>
            <DataGrid x:Name="DataGrid_Signals" ColumnWidth="80" ItemsSource="{Binding}" HorizontalAlignment="Stretch"  VerticalAlignment="Top" SelectionChanged="SignalsSelected" />
        </TabItem>
    </TabControl>

编辑: 为了更清楚,我将最小化场景。 TabItem1 - 内部有 DataGrid_Conditions; TabItem2 - 里面有 DataGrid_Signals。

这是我手动或以编程方式选择选项卡时尝试运行的另一个代码:

DataGridRow Row = (DataGridRow)DataGrid_Signals.ItemContainerGenerator.ContainerFromIndex(ID);

发生的情况是,如果我单击 tab2,则此代码不适用于 tab2 的网格。相反,它适用于之前的 tab(1) 网格。 LeftTabs.SelectedContent 是唯一未更新的属性。

【问题讨论】:

    标签: c# wpf datagrid tabcontrol


    【解决方案1】:

    我似乎无法重现您的问题。选择第二个选项卡时应打印出“DataGrid_Signals”。您还可以从SelectionChangedEventArgs 中获得对当前选定TabItem 的引用:

    private void LeftTabs_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        Debug.WriteLine(LeftTabs.SelectedIndex);
        TabItem tabItem = e.AddedItems[0] as TabItem;
        var currentDataGrid = (DataGrid)tabItem.Content;
        Debug.WriteLine(currentDataGrid.Name);
    }
    

    在此示例中,尽管当我尝试从网格对象中获取任何内容时它确实打印了“DataGrid_Signals”,但它只是为 null,因为它处于隐藏状态。

    这是因为它尚未加载。您可以强制它按尺寸呈现并安排它:

    private void LeftTabs_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (IsLoaded)
        {
            TabItem tabItem = e.AddedItems[0] as TabItem;
            var currentDataGrid = (DataGrid)tabItem.Content;
            currentDataGrid.Measure(new Size(currentDataGrid.ActualWidth, currentDataGrid.ActualHeight));
            currentDataGrid.Arrange(new Rect(0, 0, currentDataGrid.ActualWidth, currentDataGrid.ActualHeight));
            //...
        }
    }
    

    【讨论】:

    • 您的代码正确返回了当前的 DataGrid,但问题是 LeftTabs.SelectedContent 仍然返回前一个选项卡的 Grid,这使得无法编辑。在这个例子中,尽管当我尝试从网格的对象中获取任何东西时它确实打印了“DataGrid_Signals”,但它只是在隐藏时变为空。
    • 那是因为它还没有被加载。
    • 当然,这里的全部问题是为什么会发生这种情况以及如何以编程方式加载它。
    • 不幸的是它仍然不起作用。例如,在您的代码之后,如果我运行代码以从网格中获取 DataRow(请参阅我在帖子中的编辑),我应该单击它返回 null,但如果我从上一个网格中询问相同的 DataRow,它返回我正确。所以不知何故你的代码不会更新 TabControl 选择的内容。
    • @RubenC。没有。e.AddedItems[0] 肯定引用了新选择的TabItem
    【解决方案2】:

    这是一个错误,已在 .NET 4.7.1 中修复,但有些奇怪,因此针对 4.7 或更低版本的应用程序仍会获得旧行为。详情请见breaking change announcement

    【讨论】:

      猜你喜欢
      • 2015-12-07
      • 1970-01-01
      • 2016-02-20
      • 2017-02-10
      • 1970-01-01
      • 2018-04-21
      • 2010-11-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多