WPF - 在DataGridTemplateColumn中获取Combobox控件的行索引 [英] WPF - get row index for Combobox control in DataGridTemplateColumn

查看:170
本文介绍了WPF - 在DataGridTemplateColumn中获取Combobox控件的行索引的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm wondering on how to do this. I have a DataGridTemplateColumn with a simple ComboBox control inside. The combobox has a SelectionChanged event linked to it.

在更改的事件中,我想知道

In the changed event I want to know what the row index of the altered row is deriving it from the altered combobox.

我是否采用了错误的方法?
这是我有的:

Am I taking the wrong approach? Here's what I have:

<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

推荐答案

(DataGridRow)dgrMatches.ContainerFromElement(cbbLegsA)== null 不工作,因为DataGrid的ItemContainer的特定行不是你的DataTemplate中的ComboBox, code> DataGridRow ,它包含一个模板版本的ComboBox。相反,您需要使用 VisualTreeHelper .FindParent()从ComboBox中找到DataGridRow(因为你的ComboBox在DataGridRow的可视树中,而不是逻辑树)。您可以从DataGridRow参考中轻松找到行索引。但是...

(DataGridRow)dgrMatches.ContainerFromElement(cbbLegsA) == null doesn't work because the DataGrid's ItemContainer for the particular row is not the ComboBox from your DataTemplate, it is a DataGridRow that contains a 'templated' version of your ComboBox. Instead you need to use VisualTreeHelper.FindParent() to find the DataGridRow from the ComboBox (since the your ComboBox is in the visual tree of the DataGridRow, but not the logical tree). You can find the row index easily from the DataGridRow reference. However...

注释中建议的更好的方法是使用MVVM模式。您的ComboBox将绑定到ViewModel中的属性。当一个属性在ViewModel中改变时,你可以很容易地更新另一个属性来实现你想要的行为,没有任何丑陋的搜索通过视觉树,或有一堆UI代码背后。而不是一个ComboBox自动更新另一个在您的UI中的逻辑,它是一个更容易控制对象模型的视图(也称为'ViewModel')应该是。

A much better approach as suggested in the comments is to use MVVM pattern. Your ComboBox would be bound to properties in the ViewModel. When one property changes in the ViewModel, you can easily update the other one to achieve the behavior you want without any ugly searching through the visual tree, or having a bunch of UI code behind. Instead of the logic of one ComboBox automatically updating another one being in your UI, it's in a much easier to control object model of your view (aka 'ViewModel') where it should be.

这篇关于WPF - 在DataGridTemplateColumn中获取Combobox控件的行索引的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆