TabControl SelectedContent不返回当前选定的TabItem内容

时间:2018-09-12 15:05:46

标签: c# wpf datagrid tabcontrol

目前,我有一个带有多个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);
}

所选索引返回正确的选项卡索引,但其内容未更新。 假设选择了选项卡1,然后单击选项卡2。它将返回选项卡2索引和选项卡1 DataGrid名称。

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

这是TabControl,项和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是唯一未更新的属性。

2 个答案:

答案 0 :(得分:1)

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

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));
        //...
    }
}

答案 1 :(得分:0)

这是一个错误,已在.NET 4.7.1中进行了修复,但经过了修改,以使定位到4.7或更低版​​本的应用仍然可以使用旧的行为。有关详细信息,请参见breaking change announcement