0

我有一个在 XAML 中定义为 2 列的 DataGrid

<DataGrid x:Name="marketInfodg" Grid.Row="1"
ItemsSource = "{Binding ElementName=This, Path=dataTableTest}"
CanUserAddRows="False">
<DataGrid.Columns>
    <DataGridComboBoxColumn Header="Department Id" x:Name="comboboxColumn1"
         SelectedValueBinding="{Binding Department Id}" />
        <DataGridTemplateColumn x:Name="DataGridTempCol" Header="Selection">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <ComboBox
x:                  Name = "combo"
                    SelectedValue = "{Binding Selection, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                    ItemsSource = "{Binding comboBoxSelections, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"
                    DropDownOpened = "combo_DropDownOpened"
                    DisplayMemberPath = "Key"
                    IsEditable="True">
                    </ComboBox>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

构造函数代码是

_dataTableTest = new DataTable();
DataColumn dc = new DataColumn();
dc.ReadOnly = false;
dc.DataType = typeof(String);
dc.ColumnName = "Department Id";
_dataTableTest.Columns.Add(dc);

DataColumn dc1 = new DataColumn();
dc1.ReadOnly = false;
dc1.DataType = typeof(KeyValuePair<string, double>);
dc1.ColumnName = "Selection";
_dataTableTest.Columns.Add(dc1);

marketInfodg.ItemsSource = _dataTableTest.DefaultView;
var row = _dataTableTest.NewRow();
row = _dataTableTest.NewRow();
_dataTableTest.Rows.Add(row);
row["Department Id"] = "X567";
row["Selection"] = (KeyValuePair<string, double>)comboBoxSelections[0];

它有效地将单行设置为列“Department Id”=“X567”,第二列是设置为 comboBoxSelections[0] 中第一项的组合框

combo_DropDownOpened当打开任何 Combobox 下拉菜单(显然)时会触发该事件,我可以cb使用基于发件人设置变量

private void combo_DropDownOpened(object sender, EventArgs e)
{
  var cb = ((System.Windows.Controls.ComboBox)sender);
}

如何在combo_DropDownOpened事件中获取关联的行(行中的所有列)和触发组合框的行索引/编号?

4

1 回答 1

4

ComboBox 位于visual tree of the DataGrid. 如果您沿着 Visual Tree 向上移动,您会在通往 DataGrid 顶部的路上找到 DataGridRow。

您可以使用VisualTreeHelper该类走到可视化树。通常,您可以使用此方法在控件的 Visual 树中查找任何父级。将此方法放在某个实用程序类中,并在您想走到可视化树以供您的控件查找任何父级时使用 -

public static Parent FindParent<Parent>(DependencyObject child)
            where Parent : DependencyObject
{
   DependencyObject parentObject = child;

   //We are not dealing with Visual, so either we need to fnd parent or
   //get Visual to get parent from Parent Heirarchy.
   while (!((parentObject is System.Windows.Media.Visual)
           || (parentObject is System.Windows.Media.Media3D.Visual3D)))
   {
       if (parentObject is Parent || parentObject == null)
       {
           return parentObject as Parent;
       }
       else
       {
          parentObject = (parentObject as FrameworkContentElement).Parent;
       }
    }

    //We have not found parent yet , and we have now visual to work with.
    parentObject = VisualTreeHelper.GetParent(parentObject);

    //check if the parent matches the type we're looking for
    if (parentObject is Parent || parentObject == null)
    {
       return parentObject as Parent;
    }
    else
    {
        //use recursion to proceed with next level
        return FindParent<Parent>(parentObject);
    }
}

现在,在您的 dropDown 事件处理程序中,您可以使用上述函数来查找 DataGridRow,如下所示 -

private void combo_DropDownOpened(object sender, EventArgs e)
{
   var cb = ((System.Windows.Controls.ComboBox)sender);
   DataGridRow dataGridRow = FindParent<DataGridRow>(cb);
   int index = dataGridRow.GetIndex();
}
于 2012-10-07T08:12:39.157 回答