[英]How to bind an ObservableCollection<bool> to a Listbox of Checkboxes in WPF
讓我用這個問題作為前綴,說明我對C#和WPF都很新。
我正在嘗試將一組Boolean
值連接到一個包含6個復選框的容器,並在按下按鈕時存儲這些值的狀態。 我假設有一種簡單的方法可以做到這一點,因為綁定到一個集合的復選框似乎是很自然的事情,但到目前為止我看到的所有解決方案似乎都過於復雜(例如: http:// merill。 net / 2009/10 / wpf-checked-listbox / )。
我通過修改數據模板創建的復選框, ListBox
和設置ItemsSource
中的ListBox
到ObservableCollection
,但我的問題是,我不知道該怎么綁定IsChecked
來,因為我試圖將其綁定到集合中的實際對象,而不是對象的屬性。
使用IsChecked="{Binding}"
直接綁定集合的項目。
<ListBox ItemsSource="{Binding MyBooleanCollection}" >
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding Mode=OneWay}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
但是,使用此方法無法綁定到源。 因為CheckBox
的IsChecked
屬性上的綁定不是綁定項的索引。 因此,它不能更改集合,只能更改集合的項目。
要繞過該限制,您可以創建布爾值的包裝器:
public class Wrapper<T> : INotifyPropertyChanged
{
private T value;
public T Value
{
get { return value; }
set
{
{
this.value = value;
OnPropertyChanged();
}
}
}
public static implicit operator Wrapper<T>(T value)
{
return new Wrapper<T> { value = value };
}
public static implicit operator T(Wrapper<T> wrapper)
{
return wrapper.value;
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
這是一個例子:
public partial class MainWindow : Window
{
public ObservableCollection<Wrapper<bool>> MyBooleanCollection { get; private set; }
public MainWindow()
{
InitializeComponent();
DataContext = this;
MyBooleanCollection = new ObservableCollection<Wrapper<bool>>() { false, true, true, false, true };
}
}
而在XAML中:
<CheckBox IsChecked="{Binding Value}"/>
在ItemTemplate
你可以寫
<CheckBox IsChecked="{Binding Path=.}"/>
要么
<CheckBox IsChecked="{Binding Mode=OwnWay}"/>
它直接綁定到item對象,即集合中的bool
值。
但請注意,在任何一種情況下,選中或取消選中CheckBox時,不會替換集合中的綁定值。 為了在單擊CheckBox時立即更新集合,您的集合必須包含具有與IsChecked
綁定的布爾屬性的對象。
在您的情況下,這可能就像下面一樣簡單(因為您的問題聽起來像您不需要屬性更改通知):
public class BooleanHelper
{
public bool Value { get; set; }
}
綁定現在看起來像這樣:
<CheckBox IsChecked="{Binding Path=Value}"/>
該集合現在將是一個ObservableCollection<BooleanHelper>
,您可能會添加如下項目:
Items.Add(new BooleanHelper { Value = true });
通過您提供的鏈接,您還可以對CheckedListItem類使用INotifyPropertyChanged擴展,但如果您不想使用ObservableCollection。 它會是這樣的:
public class CheckedListItem : INotifyPropertyChanged
{
private int _Id;
public int Id
{
get;
set; NotifyIfAnythingChanged("Id");
}
private string _Name;
public string Name
{
get;
set; NotifyIfAnythingChanged("Name");
}
private bool _IsChecked;
public bool IsChecked
{
get;
set; NotifyIfAnythingChanged("IsChecked");
}
private void NotifyIfAnythingChanged(String propName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
你的列表框應該是這樣的:
<ListBox x:Name="MyListBox">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content={Binding Path=Name} IsChecked="{Binding Mode=TwoWay, Path=IsChecked}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
在您的代碼中,您應該只初始化ObservableCollection一次,因為對其進行的每個更改都將導致UI更新。
ObservableCollection<CheckedListItem> MyList = new ObservableCollection<CheckedListItem>();
MyListBox.ItemsSource = MyList;
現在,對MyList進行的每個更改,例如Add(),Remove()等都將影響您的UI。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.