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

时间:2015-06-16 14:41:05

标签: c# wpf wpfdatagrid

我有一个数据网格,在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 ....
        }
    }

2 个答案:

答案 0 :(得分:0)

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

例如,您可以提供适用于 ProductA DataTemplate,其中包含数据网格,以及 ProductA 的特定列;同样适用于 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>

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

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

答案 1 :(得分:0)

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

以下示例代码如何通过为DataGridComboBoxColumn.EditingElementStyle设置EventSetter(ComboBox继承自Selector),通过Selector.SelectionChangedEvent属性执行您想要的操作:

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];
    }
}