2011-02-11 58 views
1

我熟悉wpf中數據綁定的基礎知識。但是,我現在有一個問題,我不知道如何解決。用兩種列表連接的數據綁定

想象一下以下的用例:

我呼籲全球的ObservableCollection A型的「AItems」
我有B型的一些對象和每個人都有A型
的的的ObservableCollection「BItems」 BItems集合可以包含全局AItems集合的對象。

我想通過ListView可視化這個。
每行應包含一個A對象和一個複選框。
我想讓ListView顯示AItems-Collection的所有元素。分配給B對象的項目應該用選中的複選框標記。所有其他複選框應該取消選中。

我的問題是現在:
我應該如何設置datacontext?
如何使複選框將其項目插入BItems-Collection並取消選中將其刪除?

我希望任何人都能理解我的問題。

感謝您的回覆。

回答

3

我不清楚你的問題的後半部分。部分原因是因爲你的命名約定很混亂;我期望名爲BItems的集合包含B類型的對象,而不是A

所以我會改變你的命名,以免混淆。而不是A,我會打電話給第一類User,而不是B,我會打電話給第二類Group。 A Group包含一組User對象,名爲Users。全球集合是這樣的:

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

可以很容易地確定給定Useru是在任何一組:

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

容易,但計算量很大,如果你有許多團體和它們包含許多用戶。我們會在一秒鐘之內回到這一點。

馬上,我看到您的問題一個也有一個問題:

我怎麼能作出這樣的勾選複選框插入其項目的BItems收集和取消選中刪除呢?

如果我檢查一個未經檢查的用戶會發生什麼?哪些組(或多個組,由於多個組可以包含用戶)是否應該添加到?

既然你說你希望檢查項目被「分配給B對象」,那麼我將假設用戶界面一次只查看一個組 - 我們將其稱爲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 })); 

你可能避免在UserViewModel類實現INotifyPropertyChanged,並讓它提高PropertyChangedIsChecked財產每當SelectedGroup變化重建集合。

此外,它可能會負責在IsChecked屬性中包含空引用檢查,以便程序在SelectedGroupSelectedGroup.Users爲空時不會拋出異常。

+0

對不起,我混亂的命名約定。謝謝,這正是我正在尋找的。我的GUI確實總是隻顯示一個'組'。 :-) – 2011-02-14 20:04:01

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