WPF DataGridTemplateColumn与组合框绑定(MVVM模式) [英] WPF DataGridTemplateColumn with ComboBox Binding (MVVM pattern)

查看:2454
本文介绍了WPF DataGridTemplateColumn与组合框绑定(MVVM模式)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用下面的WPF的DataGrid + ComboBox的业务情景疯狂。

I am going bonkers with the following WPF DataGrid+ComboBox scenario.

我有一组看起来像班;

I have a set of classes which look like;

class Owner
{
    int ID { get; }
    string Name { get; }

    public override ToString()
    { 
        return this.Name;
    }
}

class House
{
    int ID { get; }
    Owner HouseOwner { get; set; }
}


class ViewModel
{
    ObservableCollection<Owner> Owners;
    ObservableCollection<House> Houses
}

现在我想要的结果是一个DataGrid,显示类型的行列表自家,并在其中一列,是一个组合框,它允许用户更改自家的价值.HouseOwner

Now my desired outcome is a DataGrid which shows a list of rows of type House, and in one of the columns, is a ComboBox which allows the user to change the value of House.HouseOwner.

在这种情况下,对于电网的DataContext为 ViewModel.Houses 并为组合框,我要的ItemsSource绑定到ViewModel.Owners。

In this scenario, the DataContext for the grid is ViewModel.Houses and for the ComboBox, I want the ItemsSource to be bound to ViewModel.Owners.

这甚至可能吗?我要去的精神与这个...我已经能够做的最好的就是正确地得到的ItemsSource约束,但是组合框(一DataGridTemplateColumn内)未显示每行中House.HouseOwner正确的价值观。

Is this even possible? I'm going mental with this... the best I've been able to do is to correctly get the ItemsSource bound, however the ComboBox (inside a DataGridTemplateColumn) is not showing the correct values for House.HouseOwner in each row.

请注意:如果我参加了ComboBox出来的图片,并把一个TextBlock在DataTemplate中,而不是,我可以看到正确的每一行的值,但得到既有的ItemsSource以及显示正确的价值选择是不是工作对我来说...

NOTE: If I take the ComboBox out of the picture and put a TextBlock in the DataTemplate instead, I can correctly see the values for each row, but getting both an ItemsSource as well as show the correct value in the selection is not working for me...

在我的code后面,我在窗口设置的DataContext为视图模型并在网格中,DataContext设置为 ViewModel.Houses 。对于除此组合框的一切,它的工作...

Inside my code behind, I have set the DataContext on the Window to ViewModel and on the grid, the DataContext is set to ViewModel.Houses. For everything except this combobox, it's working...

我对违规列XAML的样子;

My XAML for the offending column looks like;

    <DataGridTemplateColumn Header="HouseOwner">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <ComboBox ItemsSource="{Binding Path=DataContext.Owners, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
                            DisplayMemberPath="Name"
                            SelectedItem="{Binding HouseOwner, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
                            SelectedValue="{Binding HouseOwner.ID, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Mode=OneWay}"
                            SelectedValuePath="ID" />
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>

很想在这一个一些帮助...好像巫毒教的一个位,虽然需要...

Would love some help on this one... seems like a bit of Voodoo is required though...

推荐答案

default.kramer 的说,你需要删除的RelativeSource 从您绑定的的SelectedItem 的SelectedValue 所示(请注意,您应该添加模式=双向您绑定,在下拉列表中的变化反映在您的模型)。

as default.kramer said, you need to remove the RelativeSource from your bindings for the SelectedItem and SelectedValue like this (notice that you should add Mode=TwoWay to your binding so that the change in the combobox is reflected in your model).

<DataGridTemplateColumn Header="House Owner">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <ComboBox
                ItemsSource="{Binding Path=DataContext.Owners, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
                DisplayMemberPath="Name"
                SelectedItem="{Binding HouseOwner, Mode=TwoWay}"
                SelectedValue="{Binding HouseOwner.ID}"
                SelectedValuePath="ID"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

然而,不像他说,你不必删除了的SelectedValue 绑定。事实上,如果你删除它,它不会工作(包括的SelectedValue SelectedValuePath 应设置在这里,为你做了),因为那是什么让绑定机制,从组合框,以确定选择DataGrid的房主属性。

However, unlike he said, you don't have to remove the binding for the SelectedValue. In fact, if you remove it, it won't work (both SelectedValue and SelectedValuePath should be set here, as you've done), because that's what's allowing the binding mechanism to identify the selection from the combobox to the DataGrid's HouseOwner property.

的SelectedValue / SelectedValuePath 组合是很有趣的。 SelectedValuePath 告诉绑定的 ID 的属性所有者反对当前选择重新presents它的的SelectedValue 告诉它该值应绑定到房主。 ID 这是对DataGrid中选定的对象。

SelectedValue/SelectedValuePath combination is very interesting. SelectedValuePath tells the databinding that the ID property of the Owner object currently selected represents its value, SelectedValue tells it that that value should be bound to the HouseOwner.ID which is the selected object on the DataGrid.

因此​​,如果您删除这些绑​​定,绑定机制将唯一知道的是选择什么样的对象,并提出在ComboBox和所选项目的房主属性,他们必须是同一个对象的参考。这意味着,例如,以下是行不通的:

Therefore, if you remove those binding, the only thing the databinding mechanism will know is "what object is selected", and to make the correspondence between the selected item in the ComboBox and the HouseOwner property on the selected item in the DataGrid, they have to be "the same object reference". Meaning that, for example, the following wouldn't work:

Owners = new ObservableCollection<Owner>
                {
                    new Owner {ID = 1, Name = "Abdou"},
                    new Owner {ID = 2, Name = "Moumen"}
                };
Houses = new ObservableCollection<House>
                {
                    new House {ID = 1, HouseOwner = new Owner {ID = 1, Name = "Abdou" }},
                    new House {ID = 2, HouseOwner = new Owner {ID = 2, Name = "Moumen"}}
                };

(注意,该大厦集HouseOwners都是从业主集合中的有所不同(新))。但是,下面的的工作:

Owners = new ObservableCollection<Owner>
                {
                    new Owner {ID = 1, Name = "Abdou"},
                    new Owner {ID = 2, Name = "Moumen"}
                };
Houses = new ObservableCollection<House>
                {
                    new House {ID = 1, HouseOwner = Owners[0]},
                    new House {ID = 2, HouseOwner = Owners[1]}
                };

希望这有助于:)

Hope this helps :)

更新:在第二种情况下,你可以通过重写得到同样的结果,而不必引用是相同的等于所有者类(自然的,因为它使用的对象在第一时间进行比较)。 (感谢@ RJ罗汉在下面的评论中指出这一点)

Update: in the second case, you can get the same result without having the references being the same by overriding Equals on the Owner class (naturally, since it's used to compare the objects in the first place). (thanks to @RJ Lohan for noting this in the comments below)

这篇关于WPF DataGridTemplateColumn与组合框绑定(MVVM模式)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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