将控件绑定到 WPF 中集合/数组中的单个值
在 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; }
}
}
}
XAML:
<CheckBox IsChecked="{Binding Path=MyCollection[0], Mode=TwoWay}">
In WPF I have a collection of bool? values and I want to bind each of these to a separate checkbox programmatically. I want the bindings to be TwoWay so that changing the value of the individual item in the collection in code updates the check box and vice versa.
I have spent ages trying to figure out how to do this and I am completely stuck. With the following code the checkbox only gets the right value when the window is loaded and that's it. Changing the check box doesn't even update the value in the collection. (UPDATE: this appears to be a bug in .NET4 as the collection does get updated in an identical .NET3.5 project. UPDATE: Microsoft have confirmed the bug and that it will be fixed in the .NET4 release.)
Many thanks in advance for your help!
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; }
}
}
}
XAML:
<CheckBox IsChecked="{Binding Path=MyCollection[0], Mode=TwoWay}">
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
为了让它发挥作用,这里需要改变一些事情。首先,您需要将布尔值包装在实现 INotifyPropertyChanged 接口的对象中,以便获取您正在查找的更改通知。目前,您正在绑定到集合中未实现该接口的布尔值。为此,您可以创建一个包装类,如下所示:
然后您将希望在表单中创建这些对象而不是布尔值列表。您可能还想使用可观察集合而不是列表,以便发送添加和删除项目的通知。如下所示:
接下来要做的就是在用户界面中显示复选框列表。为此,WPF 提供了项目控件。 ListBox 是一个项目控件,因此我们可以使用它作为起点。将列表框的 itemssource 设置为 MyCollection。然后,我们需要定义每个 Wrapper 对象如何在列表框中显示,这可以通过在 Windows 资源中创建的数据模板来完成。如下所示:
这应该可以帮助您启动并运行一个简单的复选框演示,这些复选框的值绑定到布尔值列表。
There are a few things that need changing here to get this to work. Firstly you'll need to wrap your boolean value in an object that implements the INotifyPropertyChanged interface in order to get the change notification that you are looking for. Currently you are binding to boolean values in your collection which do not implement the interface. To do this you could create a wrapper class like so :
You'll then want to create these objects in your form instead of a list of booleans. You may also want to use an observable collection instead of a list so that notification of items being added and removed are sent. This is shown below:
The next thing to do is to display a list of check boxes in your ui. To do this WPF provides itemscontrols. ListBox is an itemscontrol so we can use this as a starting point. Set the itemssource of a listbox to be MyCollection. We then need to define how each Wrapper object is going to be displayed in the list box and this can be done with a datatemplate which is created in the windows resources. This is shown below :
This should get you up and running with a simple demo of checkboxes that have values bound to a list of booleans.
是什么让您认为它不起作用?它对我有用:)
这是我的测试 XAML:
这是我的代码:(
其余部分与您的相同)
我在
Button_Click
上放置了一个断点并检查了MyCollection[0]
它根据CheckBox
的IsChecked
值进行更新。尝试将您的集合类型从
List
更改为ObservableCollection
也许这就是您认为它不适合您的原因(事实上,更改在您看来,该集合不会反映在其他任何地方)。What makes you think it's not working? It's working for me :)
Here's my test XAML:
Here's my code behind:
(the rest is the same as yours)
I placed a breakpoint on
Button_Click
and checkedMyCollection[0]
it was updated according to theIsChecked
value of theCheckBox
.Try changing your collection type from
List<bool?>
toObservableCollection<bool?>
perhaps that is the reason you think it's not working for you (the fact that changes to the collection are not reflected anywhere else in your view).将
List
更改为ObservableCollection
。列表不会引发 WPF 更新 UI 所需的更改通知。 ObservableCollection 可以做到这一点。这处理列表条目更改并且复选框需要相应更新的情况。另一方面,即使使用
List
,它也适用于我——即切换复选框会修改集合中的值。您的绑定语法当然是正确的。Change your
List<bool?>
to anObservableCollection<bool?>
. A List does not raise the change notifications that WPF needs to update the UI. An ObservableCollection does. This handles the case where the list entry is changed and the CheckBox needs to update accordingly.In the other direction, it works for me even with a
List<bool?>
-- i.e. toggling the checkbox modifies the value in the collection. Your binding syntax is certainly correct.