简体   繁体   English

在WPF中,如何将Checkbox的IsChecked绑定到List <>。Contains?

[英]In WPF, how do I two-way bind a Checkbox's IsChecked to property to List<>.Contains?

Sorry if the wording of my question is not great or if this has been answered somewhere, I've searched, but I don't really know how well to explain what I am trying to do. 很抱歉,如果我的问题措辞不好,或者是否已经在某个地方回答了该问题,我已经进行了搜索,但是我真的不知道如何很好地解释我要做什么。

Here's a simple testbed I've partially set up to help explain: 这是我已部分设置的一个简单测试床,以帮助说明:

MainWindow.xaml: MainWindow.xaml:

<Window x:Class="wpfExample.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:wpfExample"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>

    <ListView Grid.Column="0" ItemsSource="{Binding People}" DisplayMemberPath="Name"/>

    <ListBox Grid.Column="1" ItemsSource="{Binding Interests}" Margin="0,4,4,4">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <CheckBox Content="{Binding Name}"/>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

</Grid>

MainWindow.xaml.cs: MainWindow.xaml.cs:

using System;
using System.Collections.ObjectModel;
using System.Windows;

namespace wpfExample
{
    public class Person
    {
        public string Name { get; set; }
        public ObservableCollection<Guid> Interests { get; set; }
    }

    public class Interest
    {
        public Guid Id { get; set; }
        public string Name { get; set; }
    }

    public class Data
    {
        public ObservableCollection<Person> People { get; set; }
        public ObservableCollection<Interest> Interests { get; set; }
    }

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            DataContext = new Data
            {
                People = new ObservableCollection<Person>
                {
                    new Person {Name="Fred", Interests=new ObservableCollection<Guid>() },
                    new Person {Name="Jane", Interests=new ObservableCollection<Guid>() },
                    new Person {Name="Zach", Interests=new ObservableCollection<Guid>() }
                },
                Interests = new ObservableCollection<Interest>
                {
                    new Interest {Name="Gardening", Id=Guid.NewGuid() },
                    new Interest {Name="Writing", Id=Guid.NewGuid() },
                    new Interest {Name="Avoiding Tax", Id=Guid.NewGuid() }
                }
            };

            InitializeComponent();
        }
    }
}

So I have a DataContext that contains two lists. 所以我有一个包含两个列表的DataContext。 One contains Interests, which have a name and an ID. 一个包含兴趣,其中包含一个名称和一个ID。 The other contains People which have a name and a list of IDs of interests. 另一个包含具有名称和兴趣ID列表的人员。

When a Person is selected in the UI, I want to be able to add and remove IDs of interests to their respective list, hence the ListView in column 1 is bound to the list of Interests, but how do I correctly bind up the IsChecked property of the checkboxes in the list? 当在UI中选择一个Person时,我希望能够向各自的列表中添加和删除兴趣ID,因此第1列中的ListView已绑定到兴趣列表,但是如何正确地绑定IsChecked属性列表中的复选框?

In my full project, I've been able to successfully read properties of the selected Person's interest list by using a MultiBinding for IsChecked with a MultiValueConverter to pass both the Id of the Interest and the List of Interests of the Person through together (since you can't use binding with the parameter for a 'normal' value converter). 在我的整个项目中,通过使用带有MultiValueConverter的IsChecked的MultiBinding和MultiValueConverter,可以成功读取选定人员的兴趣列表的属性,从而一起传递人员的兴趣ID和人员的兴趣列表(自您以来不能将参数的绑定用于“常规”值转换器)。 I feel that this solution is a little bit of an abuse of the converter, but I'm happy to stick with it if necessary. 我觉得此解决方案有点滥用转换器,但如有必要,我很乐意坚持使用。

How do I implement a system that will allow me to add and remove Interest Guids to a Person's list of interests when the checkbox is toggled? 我如何实现一个系统,当复选框切换时,该系统将允许我在个人兴趣列表中添加和删除兴趣指南? Is there a cleaner way of doing this? 有没有更干净的方法可以做到这一点? I don't want to change the model if it can be avoided. 如果可以避免,我不想更改模型。

I wouldn't say your MultiConverter solution is an abuse at all; 我不会说您的MultiConverter解决方案完全是一种滥用。 you are doing exactly what converters should (take a set of data and converting to the target type, then going back). 您正在执行转换器应该执行的操作(获取一组数据并转换为目标类型,然后返回)。

That being said; 话虽如此; converters are a bit of a mess due to their generality (use of object ), and that goes double for Multi Converters, so if you want a different solution I would recommend creating a view model wrapper for Interest ; 转换器由于它们的通用性(使用object )而有些混乱,对于Multi Converters来说是双重的,因此,如果您想要一个不同的解决方案,我建议为Interest创建一个视图模型包装器; say Selectable<T> : Selectable<T>

public class Selectable<T>
{
     public T Data {get; set;}
     public bool Selected {get; set;}
}

Then update your property 然后更新您的财产

public ObservableCollection<Selectable<Interest>> Interests { get; set; }

And bind IsChecked directly to Selected 并将IsChecked直接绑定到Selected

Then whenever the selected Person is changed you can update the Selected property appropriately; 然后,无论何时更改选定的Person ,您都可以适当地更新Selected属性。 store the previous value to the other Person , etc. It somewhat depends on when the user action needs to be reflected in the model. 将先前的值存储给其他Person等。这在某种程度上取决于何时需要在模型中反映用户操作。

All that being said, both approaches will be perfectly valid, it just comes down to what you are most comfortable with. 综上所述,这两种方法都是完全有效的,这取决于您最满意的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将 WPF 复选框的 IsChecked 属性绑定到非窗口对象的布尔属性 - How can I bind a WPF checkbox's IsChecked property to a boolean property of an object that is not a window 如何将两个东西绑定到复选框的 IsChecked 属性? - How to bind two things to IsChecked property of checkbox? WPF - CheckBox IsChecked by List 其中包含字符串 - WPF - CheckBox IsChecked by List where it contains string 如何将布尔值列表分配给 WPF 中生成的 Checkbox IsChecked 属性? - How to assign a List of Booleans to a generated Checkbox IsChecked property in WPF? 如何为我的bool属性正确实现INotifyPropertyChanged并绑定到CheckBox.IsChecked? - How do I correctly implement INotifyPropertyChanged for my bool property and bind to CheckBox.IsChecked? WPF复选框IsChecked双向绑定不起作用 - WPF checkbox IsChecked two way binding not working WPF双向绑定到属性的属性以替换父属性 - WPF Two-way binding to property's property to replace the parent property 如何修复 WPF Datagrids 中的“双向绑定需要路径或 XPath”异常? - How do I fix "Two-way binding requires Path or XPath" exception in WPF Datagrids? 如何将 TextBox 的 Text 双向数据绑定到 Dependency 属性 - How to Two-way databind a TextBox's Text to a Dependency property 如何将WPF ListView绑定到列表中每个元素的属性? - How do I bind a WPF ListView to a property of each element in a list?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM