簡體   English   中英

如何綁定ObservableCollection <bool> 到WPF中的復選框列表框

[英]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中的ListBoxObservableCollection ,但我的問題是,我不知道該怎么綁定IsChecked來,因為我試圖將其綁定到集合中的實際對象,而不是對象的屬性。

使用IsChecked="{Binding}"直接綁定集合的項目。

<ListBox ItemsSource="{Binding MyBooleanCollection}" >
    <ListBox.ItemTemplate>
        <DataTemplate>
            <CheckBox IsChecked="{Binding Mode=OneWay}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

但是,使用此方法無法綁定到源。 因為CheckBoxIsChecked屬性上的綁定不是綁定項的索引。 因此,它不能更改集合,只能更改集合的項目。

更新

要繞過該限制,您可以創建布爾值的包裝器:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM