通过两个列表进行数据绑定

时间:2011-02-11 10:49:32

标签: wpf data-binding

我熟悉wpf中数据绑定的基础知识。但是我现在有一个问题,我想知道如何解决。

想象一下以下用例:

我有一个名为“AItems”的全局ObservableCollection,类型为A.
我有一些B类对象,每个对象都有一个类型为A的ObservableCollection“BItems” BItems集合可以包含全局AItems集合的对象。

我希望通过ListView将其可视化 每行应包含一个A-Object和一个复选框 我希望ListView显示AItems-Collection的所有元素。分配给B-Object的项目应使用选中的复选框进行标记。应取消选中所有其他复选框。

我现在的问题是:
我该如何设置datacontext?
如何选中复选框将其项目插入BItems-Collection并取消选中将其删除?

我希望任何人都能理解我的问题。

感谢您的回复。

2 个答案:

答案 0 :(得分:3)

我不清楚你问题的后半部分。部分原因是因为你的命名惯例令人困惑;我希望名为BItems的集合包含B类型的对象,而不是A

所以我会稍微改变你的命名,这样我就不会感到困惑。我将调用第一个班级A,而不是User,而不是B,我将调用第二个班级GroupGroup包含User个对象的集合,名为Users。全局集合看起来像这样:

List<User> Users;
List<Group> Groups;

很容易确定给定的User u是否在任何群组中:

return Groups.Where(g => g.Users.Contains(u)).Any();

如果您有许多群组并且包含许多用户,则很容易,但计算成本很高。我们将在一秒钟内回到那里。

马上,我发现你的一个问题出了问题:

  

如何选中复选框将其项目插入BItems-Collection并取消选中将其删除?

如果我检查未经检查的用户会怎么样?应该将哪个组(或组,因为多个组可以包含用户)添加到?

既然你说要将选中的项目“分配给B-Object”,我将假设UI一次仅查看一个组 - 我们将其称为{{1 }}。这很好,因为SelectedGroup比我上面显示的查询便宜得多。

如果是这样,那么您需要做的是将g.Users.Contains(u)包装在一个公开User属性的类中。我打电话给这个班级IsChecked,因为那就是它。该类需要三个属性(至少):

UserViewModel

您的public User User { get; set; } public Group SelectedGroup { get; set; } public bool IsChecked { get { return SelectedGroup.Users.Contains(this.User); } set { if (value != IsChecked) { if (IsChecked) { SelectedGroup.Users.Remove(this.User); } else { SelectedGroup.Users.Add(this.User); } } } } 绑定了一个ListView,名为ObservableCollection<UserViewModel>。每当设置UserViewModels时,您需要重建此集合:

SelectedGroup

您可以通过在UserViewModels = new ObservableCollection<UserViewModel>( Users.Select(u => new UserViewModel { User=u, SelectedGroup=SelectedGroup })); 课程中实施INotifyPropertyChanged来避免重建该集合,并在UserViewModel更改时让PropertyChanged属性为IsChecked

此外,它可能负责在SelectedGroup属性中包含空引用检查,以便在IsCheckedSelectedGroup为空时程序不会引发异常。

答案 1 :(得分:0)

您可以将列表框绑定到Aitems并使用转换器设置isChecked属性

<ListBox ItemsSource="{Binding AItems}">
    <ListBox.ItemTemplate>
        <DataTemplate>
                <CheckBox Content="{Binding}" IsChecked="{Binding Mode=OneTime, Converter={StaticResource BItemCheckConverter}}"></CheckBox>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

public class BItemCheckConverter : IValueConverter
{
    public List<Aitems> BItems { get; set; }

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (BItems.Contains((value as Aitems)) return true;
        else return false
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

我不知道你的对象模型是怎样的,所以按原样使用上面的代码。

HTH