将ComboBox绑定到DataGrid Entry

时间:2014-07-14 20:42:12

标签: wpf data-binding combobox wpfdatagrid datagridtemplatecolumn

解决了问题,但仍然有疑问。请参阅帖子的结尾,或阅读上下文。

我正在尝试设置一个WPF数据网格,其中包含许多带有组合框的模板化列。特别是我在数据绑定方面遇到了麻烦。

数据模型
首先,我有Entry,其中包含4个属性:

  • Name
  • Customer
  • Color
  • Type

最有趣的属性是Color,它还有两个子属性:

  • ColorString
  • Index

目标
我需要创建一个数据网格,其中每一行对应一个Entry对象。 Customer,Color和Type属性都具有组合框,允许选择动态填充的选项。我需要为每个组合框选择的项目绑定到条目的相应属性。

截图
enter image description here

<小时/> 的的问题:
如何正确设置数据网格和每个组合框的数据上下文?
对于数据网格,我以编程方式将数据上下文设置为ObservableCollection的实例。

private ObservableCollection<Entry> entries = new ObservableCollection<Entry>();

public MainWindow()
{
    InitializeComponent();

    entries.Add(new Entry("Foo", "Customer1", new MyColor("#00000000", 1), "Type1"));
    entries.Add(new Entry("Bar", "Customer2", new MyColor("#00000000", 1), "Type2"));
    LayerMapGrid.DataContext = entries; //Set data-context of datagrid
}

对于彩色组合框,我在我的XAML中使用ObjectDataProvider

<Window.Resources>
    <ObjectDataProvider x:Key="Colors" ObjectType="{x:Type local:MyColor}" MethodName="GetColors"/>
</Window.Resources>

这是我绑定ObjectDataProvider的方式

<ComboBox ItemsSource="{Binding Source={StaticResource Colors}}"/>

MyColor课程中,我创建了以下方法:

public static ObservableCollection<MyColor> GetColors()
{
    ObservableCollection<MyColor> colors = new ObservableCollection<MyColor>();
    //... Fill collection... (omitted for brevity)
    return colors;
}

好消息是以上所有代码都有效。然而,这是解决手头问题的好方法吗?

这是我的下一个更重要的问题:
如何绑定组合框的选定项目以更新ObservableCollection<Entry>

我知道我需要设置UpdateSourceTrigger="PropertyChanged",以便更新我的源Entry集合。

这是我当前用于设置整个数据网格的XAML代码。注意:我还没有实现客户并输入组合框。我真的只关心颜色组合框:

<DataGrid ItemsSource="{Binding}" AutoGenerateColumns="False" Name="LayerMapGrid">
        <DataGrid.Columns>

            <!--Name Column-->
            <DataGridTemplateColumn Header="Name">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <Label Content="{Binding Name, UpdateSourceTrigger=PropertyChanged}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
                <DataGridTemplateColumn.HeaderStyle>
                    <Style TargetType="DataGridColumnHeader">
                        <Setter Property="Control.HorizontalContentAlignment" Value="Center" />
                    </Style>
                </DataGridTemplateColumn.HeaderStyle>
            </DataGridTemplateColumn>

            <!--Customer Column-->
            <DataGridTemplateColumn Header="Customer">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox SelectedItem="{Binding CustomerName, UpdateSourceTrigger=PropertyChanged}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>

            <!--Color Column-->
            <DataGridTemplateColumn Header="Color">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox ItemsSource="{Binding Source={StaticResource Colors}}" SelectedItem="{Binding Color, ElementName=LayerMapGrid, UpdateSourceTrigger=PropertyChanged}">
                            <ComboBox.ItemTemplate>
                                <DataTemplate>
                                    <DockPanel Margin="2">
                                        <Border DockPanel.Dock="Left" HorizontalAlignment="Right" BorderThickness="1" BorderBrush="Black" Margin="1" Width="10" Height="10">
                                            <Rectangle Name="ColorRec" Fill="{Binding ColorString}"/>
                                        </Border>
                                        <TextBlock Padding="4,2,2,2" Text="{Binding ColorString}" VerticalAlignment="Center"/>
                                    </DockPanel>
                                </DataTemplate>
                            </ComboBox.ItemTemplate>
                        </ComboBox>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>

            <!--Type Column-->
            <DataGridTemplateColumn Header="Type">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox SelectedItem="{Binding Type, UpdateSourceTrigger=PropertyChanged}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>

非常感谢您的协助。我一直在墙上撞了大约16个小时。

-Nick Miller

修改
我找到了解决方案(并且在请求帮助之后一直都是这样),但我不明白它是如何工作的。

在XAML中,我已将组合框绑定更改为:

<ComboBox ItemsSource="{Binding Source={StaticResource Colors}}" SelectedItem="{Binding Color, UpdateSourceTrigger=PropertyChanged}">

这到底发生了什么?

为什么组合框现在指的是数据网格的数据上下文?当我将ItemsSource设置为指向ObjectDataProvider时,是否会覆盖?

1 个答案:

答案 0 :(得分:1)

  

如何正确设置数据网格和每个组合框的数据上下文?

你没有。通常在WPF中,我们在DataContext上设置UserControl属性,或在我们设计的Window上设置 not 在单个控件上。通过这种方式, all 视图中的控件可以访问数据属性。

  

如何绑定组合框的选定项目以更新ObservableCollection?

同样,你不做你正在做的事情。您应该只在后面的代码中使用ObjectDataProvider类型的属性,而不是使用ObservableCollection<MyColor>,并直接绑定到该属性。您应该将public Entries属性绑定到DataGrid.ItemsSource属性,private entries字段设置为DataContext。您真的需要阅读MSDN上的Data Binding Overview页面以获得进一步的帮助。

DataContext的{​​{1}}设置为自身(通常不是一个好主意):

MainWindow.xaml

然后在public MainWindow() { InitializeComponent(); Entries.Add(new Entry("Foo", "Customer1", new MyColor("#00000000", 1), "Type1")); Entries.Add(new Entry("Bar", "Customer2", new MyColor("#00000000", 1), "Type2")); DataContext = this; //Set DataContext to itself so you can access properties here }

MainWindow.xaml

<DataGrid ItemsSource="{Binding Entries}" ... /> 每行中的DataTemplate会自动将数据绑定集合中的相关项目设置为DataGrid,因此您可以自动访问相关属性类。再次......无需手动设置任何DataContext。如果您还有其他问题,请阅读链接的文章,因为答案就在那里。


更新&gt;&gt;&gt;

让我们明确一些事情......我你的个人导师,所以这将是我的最后答复。

  

如何克服继承数据网格数据上下文的组合框?

要将数据绑定到设置为DataContext的对象,您只需使用有效的Window.DataContext和一些基本逻辑:

Binding Path