WPF(mvvm)数据绑定itemssource和selecteditem到不同的模型

时间:2016-07-16 00:37:42

标签: c# wpf mvvm data-binding

我有一个WPF数据绑定问题,我没有过去。我有一个MVVM设置,如下所示:

public class ModelA
{
    public int Id
    {
        //Property uses INotifyPropertyChanged
    }
}

public class ModelB
{
    public ModelA The_A
    {
        //Property uses INotifyPropertyChanged
    }
}

public class ViewModel
{
    public IEnumerable<ModelA> ModelAList
    {
        //Property uses INotifyPropertyChanged
    }

    public IEnumerable<ModelB> ModelBList
    {
        //Property uses INotifyPropertyChanged
    }
}

我的XAML的DataContext是ViewModel(惊喜),我已经有了这个ListBox:

<ListBox ItemsSource="{Binding ModelBList}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <ComboBox
                ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.ModelAList"
                SelectedItem="{Binding The_A}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

当我打开窗口时,ComboBox没有选择项目,但如果我从复选框中选择了某些内容,则The_A会被设置为我选择的内容。

我的猜测是我的ModelAList中的ModelA与ModelB中的ModelA不同。有没有办法让这个数据绑定工作?也许我错过了一些明显的东西,或者我没有正确地解决问题。

非常感谢!

2 个答案:

答案 0 :(得分:3)

您的数据绑定似乎是错误的。这就是为什么它不起作用。 由于您的视图令人惊讶地绑定到var strInput= "abcd x abcd"; var translated = strInput.replace("x", "y"); 类,因此该ViewModel类应该保存来自相应视图的所有绑定。

你的itemssource正确绑定到ModelAList IEnumerable。

但是所选项目与其他一些课程相关联。属性。因此它不会起作用。您还需要将所选项目设置为用于项目源的数据类型。

因此,在ViewModel类中创建一个属性,如下所示:

ViewModel

然后将其绑定到SelectedItem,如下所示:

private ModelA _selectedComboBoxItem;
public ModelA SelectedComboBoxItem
{
    get { return _selectedComboBoxItem; }
    set 
    { 
       _selectedComboBoxItem = value; 
       Propertychanged(this, "SelectedComboBoxItem");
    }
}

这显然有效。

编辑: 根据提问者的要求添加更多详细信息。

假设你有十几个橘子。如果你让一个人从他们那里随机挑选,你会得到什么?橙子本身对吗?这也是背后的想法。如果选择组合框项目,它将与其源类型完全相同。

如果在同一个列表项中有许多组合框,则可以更改ItemsSource数据类型以容纳那么多列表或属性。

例如:假设我有一个包含2个组合框和2个文本框的列表。所以我的itemssource将是ObservableCollection,这个可观察的集合将保存2个枚举,以及2个字符串,用于保存4个控件的值。如果您愿意,还可以创建2个附加属性来绑定每个组合框的选定项目。

答案 1 :(得分:-1)

经过一段时间的讨论,我找到了问题的解决方案。 IDisposable的回答指出,组合框不能同时绑定到两个单独的对象。因此,当实例化ViewModel时(并且在加载了ModelA的列表之后),可以将列表复制到每个ModelB中以进行绑定。解决方案如下。

public class ModelA
{
    public int Id
    {
        //Property uses INotifyPropertyChanged
    }
}

public class ModelB
{
    public ModelA The_A
    {
        //Property uses INotifyPropertyChanged
    }

    public IEnumerable<ModelA> The_A_List
    {
        //Property uses INotifyPropertyChanged
    }
}

public class ViewModel
{
    public ViewModel()
    {
        //Load lists
        foreach (var b in ModelBList)
        {
            b.The_A_List = ModelAList;
        }
    }

    public IEnumerable<ModelA> ModelAList
    {
        //Property uses INotifyPropertyChanged
    }

    public IEnumerable<ModelB> ModelBList
    {
        //Property uses INotifyPropertyChanged
    }
}

然后在xaml中提供以下绑定:

<ListBox ItemsSource="{Binding ModelBList}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <ComboBox
                ItemsSource="{Binding The_A_List}"
                SelectedItem="{Binding The_A}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

一切都很好。再次感谢IDisposable的帮助,让我踏上启蒙之路。

相关问题