WPF - 获取 DataGridTemplateColumn 中组合框控件的行索引

本文关键字:控件 索引 组合 获取 DataGridTemplateColumn WPF | 更新日期: 2023-09-27 18:37:11

我想知道如何做到这一点。我有一个DataGridTemplateColumn里面有一个简单的ComboBox控件。组合框有一个链接到它的SelectionChanged事件。

在更改的事件中,我想知道更改行的行索引是从更改的组合框中派生的。

我是否采取了错误的方法?这是我所拥有的:

<DataGrid AutoGenerateColumns="False" Margin="5,10,5,5"
            x:Name="dgrMatches" ItemsSource="{Binding .}"
            CanUserAddRows="False" CanUserDeleteRows="False" CanUserReorderColumns="False" CanUserSortColumns="False"
            SelectionMode="Single" SelectionUnit="FullRow" IsReadOnly="False"
            RowStyle="{DynamicResource EditableRows}" CellStyle="{DynamicResource EditableTableCells}">
        <DataGrid.Columns>
            <DataGridTextColumn ... />
            <DataGridTemplateColumn Header="Legs won" Width="Auto">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox Name="cbbLegsWonA"
                                SelectedIndex="{Binding LegsWonA, Mode=TwoWay}"
                                ItemsSource="{Binding NumberOfLegs}"
                                SelectionChanged="cbbLegsWonA_SelectionChanged" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            <!-- @Chris Eelmaa -->
            <DataGridTemplateColumn Header="Legs won" Width="Auto">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox Name="cbbLegsWonB"
                                SelectedIndex="{Binding LegsWonB, Mode=TwoWay}"
                                ItemsSource="{Binding NumberOfLegs}"
                                SelectionChanged="cbbLegsWonB_SelectionChanged" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            <DataGridTextColumn ... />
        </DataGrid.Columns>
    </DataGrid>

和事件处理程序:

private void cbbLegsWonA_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    ComboBox cbbLegsA = e.Source as ComboBox; // Altered combobox
    int rowIndex = -1;
    if (cbbLegsA.Tag == null)
    {
        DataGridRow row = (DataGridRow)dgrMatches.ContainerFromElement(cbbLegsA);
        rowIndex = row.GetIndex();
        cbbLegsA.Tag = rowIndex;
    }
    else
    {
        Int32.TryParse(cbbLegsA.Tag.ToString(), out rowIndex);
    }
//@ChrisEelmaa: Basically, change the bound list and refresh the items in the datagrid
//The debugger doesn't get to this point, ofcourse
SingleMatch match = matches.ElementAt(rowIndex); // Get the current match out of the bound list
match.LegsWonA = cbbLegsA.SelectedIndex; // Manually change second combobox item
dgrMatches.Items.Refresh();
...
}

这不起作用:(DataGridRow)dgrMatches.ContainerFromElement(cbbLegsA) == null

WPF - 获取 DataGridTemplateColumn 中组合框控件的行索引

(DataGridRow)dgrMatches.ContainerFromElement(cbbLegsA) == null不起作用

,因为特定行的 DataGrid 的 ItemContainer 不是 DataTemplate 中的 ComboBox,而是包含 ComboBox 的"模板化"版本的DataGridRow。相反,您需要使用 VisualTreeHelper.FindParent() 从 ComboBox 中查找 DataGridRow(因为您的 ComboBox 位于 DataGridRow 的可视化树中,而不是逻辑树中)。您可以从 DataGridRow 引用中轻松找到行索引。然而。。。

注释中建议的更好的方法是使用 MVVM 模式。组合框将绑定到视图模型中的属性。当 ViewModel 中的一个属性发生更改时,您可以轻松地更新另一个属性以实现所需的行为,而无需在可视化树中进行任何丑陋的搜索,或者隐藏一堆 UI 代码。与一个 ComboBox 自动更新另一个 ComboBox 的逻辑不同,它更容易控制视图的对象模型(也称为"视图模型")的位置。