WPF- 将更改事件添加到自动生成的 DataGridComboBoxColumn

WPF- Add change event to autogenerated DataGridComboBoxColumn

我有一个数据网格,在 DataGrid.AutoGeneratingColumn 事件中我将一些列更改为 DataGridComboBoxColumns。

同时我还想向那个新的组合框添加一个选择更改事件,但不知道如何访问 DataGridComboBoxColumn 中的组合框控件。

    private void dgGrid_AutogeneratingColumns(object sender, DataGridAutoGeneratingColumnEventArgs e)
    {
        var cb = new DataGridComboBoxColumn();
        switch (e.PropertyName)
        {
            case "name":

                using (Entities context = new Entities())
                {
                    List<object> fNames = (from x in context.view
                        select new object {objectname = x.objectname}).ToList<object>();

                    cb.Header = "xxx";
                    cb.ItemsSource = xxx;
                    cb.SelectedItemBinding = new Binding("xxx");
                    e.Column = cb;

                    //Get reference to combobox in this new column
                    //Add event to it
                    //?????

                }
                break;
            //more ....
        }
    }

为什么不在xaml中声明列,并为每一列提供列模板?然后您可以订阅选择更改事件。或者,改为绑定到 "SelectedItem" 组合框 属性。

例如,您可以为 ProductA 提供一个 DataTemplate,其中包含数据网格和 ProductA[=22] 的特定列=];同样适用于 ProductB.

<DataTemplate DataType="{x:Type model:ProductA}">
    <DataGrid AutoGenerateColumns="False"
              ItemsSource="{Binding Products}">
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding ProductName}"
                                Header="ProductName"
                                IsReadOnly="True"></DataGridTextColumn>

            <DataGridTemplateColumn Header="Category">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding CategoryName}" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>

                <DataGridTemplateColumn.CellEditingTemplate>
                    <DataTemplate>
                        <ComboBox ItemsSource="{Binding Categories}"
                                  SelectedItem="{Binding SelectedCategory"}
                                  IsSynchronizedWithCurrentItem="True" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellEditingTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>
</DataTemplate>

然后要使用数据模板,您将使用 ContentPresenter,它会根据 SelectedProduct 类型解析正确的数据模板。

<ContentPresenter Content="{Binding SelectedProductType}" />

您无法从 DataGrid.AutoGeneratingColumn 事件处理程序访问 ComboBox 实例,因为 ComBox 仅在该列的单元格进入编辑模式时创建,并且每次该单元格进入编辑模式时都会创建新的 ComboBox 实例。

这是一个示例代码,如何通过 DataGridComboBoxColumn.EditingElementStyle property by setting EventSetter for Selector.SelectionChangedEvent(ComboBox 继承自 Selector)来执行您想要的操作:

private void dgGrid_AutogeneratingColumns(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
    switch (e.PropertyName)
    {
        case "name":

            var cb = new DataGridComboBoxColumn();

            // Old...
            cb.Header = "Name";
            cb.ItemsSource = new List<string>() { "Option1", "Option2", "Option3" };
            cb.SelectedItemBinding = new Binding("name");

            // NEW
            cb.EditingElementStyle = new Style(typeof(ComboBox))
            {
                Setters =
                {
                    new EventSetter(Selector.SelectionChangedEvent, new SelectionChangedEventHandler(OnComboBoxSelectionChanged))
                }
            };

            e.Column = cb;
            break;
    }
}

private static void OnComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    // We must check that both RemovedItems and AddedItems are not empty,
    // because this event also fires when ComboBox is initialized (when entering edit mode), but then RemovedItems is empty.
    if (e.RemovedItems.Count > 0 && e.AddedItems.Count > 0)
    {
        var newlySelectedName = (string)e.AddedItems[0];
    }
}