将控件绑定到WPF中的集合/数组中的单个值

Mat*_*ins 4 .net c# data-binding wpf two-way-binding

在WPF我有一个bool的集合?我希望以编程方式将这些值中的每一个绑定到一个单独的复选框.我希望绑定是TwoWay,以便在代码中更改集合中单个项的值更新复选框,反之亦然.

我花了很长时间试图弄清楚如何做到这一点,我完全卡住了.使用以下代码,复选框仅在窗口加载时获得正确的值,就是这样.更改复选框甚至不更新集合中的值.(更新:这似乎是.NET4中的一个错误,因为该集合在相同的.NET3.5项目中得到更新.更新:Microsoft已经确认了该错误,并且它将在.NET4版本中得到修复.)

非常感谢您的帮助!

C#:

namespace MyNamespace
{
    public partial class MyWindow : Window, INotifyPropertyChanged
    {
        public MyWindow()
        {
            InitializeComponent();
            DataContext = this;
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
               PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }

        public List<bool?> myCollection = new List<bool?>
            { true, false, true, false, true, false };

        public List<bool?> MyCollection
        {
            get { return myCollection; }
            set { myCollection = value; }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

XAML:

<CheckBox IsChecked="{Binding Path=MyCollection[0], Mode=TwoWay}">
Run Code Online (Sandbox Code Playgroud)

mat*_*000 5

有一些事情需要在这里改变以使其发挥作用.首先,您需要将布尔值包装在实现INotifyPropertyChanged接口的对象中,以获取您要查找的更改通知.目前,您绑定到集合中未实现接口的布尔值.为此,您可以创建一个包装类,如下所示:

  public class Wrapper: INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        private bool val = false;

        public bool Val
        {
            get { return val; }
            set
            {
                val = value;
                this.OnPropertyChanged("Val");
            }
        }

        public Wrapper(bool val)
        {
            this.val = val;
        }

    }
Run Code Online (Sandbox Code Playgroud)

然后,您需要在表单中创建这些对象,而不是布尔列表.您可能还希望使用可观察集合而不是列表,以便发送添加和删除项目的通知.如下所示:

public Window1()
    {
        InitializeComponent();
        this.DataContext = this;
    }

    private ObservableCollection<Wrapper> myCollection = new ObservableCollection<Wrapper>()
        {new Wrapper(true), new Wrapper(false), new Wrapper(true)};


    public ObservableCollection<Wrapper> MyCollection
    {
        get { return myCollection; }
    }
Run Code Online (Sandbox Code Playgroud)

接下来要做的是在你的UI中显示一个复选框列表.为此,WPF提供了itemscontrols.ListBox是一个itemscontrol,所以我们可以用它作为起点.将列表框的itemssource设置为MyCollection.然后,我们需要定义每个Wrapper对象将如何显示在列表框中,这可以通过在Windows资源中创建的datatemplate来完成.如下所示:

<Window.Resources>
    <DataTemplate x:Key="myCollectionItems">
        <CheckBox IsChecked="{Binding Path=Val, Mode=TwoWay}"></CheckBox>
    </DataTemplate>
</Window.Resources>
<Grid>
    <ListBox ItemsSource="{Binding Path=MyCollection}" ItemTemplate="{StaticResource myCollectionItems}"></ListBox>
</Grid>
Run Code Online (Sandbox Code Playgroud)

这应该让您启动并运行一个简单的复选框演示,其中的值绑定到一个布尔列表.