C# 将复选框状态绑定到WPF中的位数组

C# 将复选框状态绑定到WPF中的位数组,c#,wpf,xaml,data-binding,C#,Wpf,Xaml,Data Binding,在尝试学习WFP的过程中,我承担了将一些旧的Winform应用程序移植到WPF并尝试坚持MVVM模型的任务 在Winform应用程序中,我有一组复选框,用于更改位数组的状态,然后通过TCP发送。简单的东西 在WPF和数据绑定中我将如何做到这一点?如何将特定复选框绑定到位数组中的特定位?我在VM中找到的所有关于此databind to single boolean属性的示例 编辑: 我在这里通过使用ObservableCollection>找到了解决方案: 我不明白的是: public stat

在尝试学习WFP的过程中,我承担了将一些旧的Winform应用程序移植到WPF并尝试坚持MVVM模型的任务

在Winform应用程序中,我有一组复选框,用于更改位数组的状态,然后通过TCP发送。简单的东西

在WPF和数据绑定中我将如何做到这一点?如何将特定复选框绑定到位数组中的特定位?我在VM中找到的所有关于此databind to single boolean属性的示例

编辑:

我在这里通过使用ObservableCollection>找到了解决方案:

我不明白的是:

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;
}
公共静态隐式运算符包装器(T值)
{
返回新包装{value=value};
}
公共静态隐式运算符T(包装器)
{
返回wrapper.value;
}

在wrapper类中,是否有人可以解释它的作用以及为什么需要它?

使用MVVM的好处是,您可以根据需要查看模型

  • 创建一个Item类来跟踪数组中每个位的状态
  • 使用项目对象的可观察集合创建MVVM视图模型
  • 在代码隐藏中数据绑定视图模型
  • 用绑定信息装饰您的xaml
  • 就这样!享受吧

    C#

    使用系统集合;
    使用System.Collections.ObjectModel;
    使用系统组件模型;
    使用System.Linq;
    使用System.Runtime.CompilerServices;
    使用System.Windows;
    命名空间数据绑定位数组
    {
    /// 
    ///1.创建一个Item类来跟踪数组中每个位的状态。
    /// 
    /// 
    公共类项目:INotifyPropertyChanged
    {
    公共事件属性更改事件处理程序属性更改;
    公共int位数组索引{get;set;}
    公共位数组ParentBitArray{get;set;}
    私人住宅被检查;
    公共项(int-bitArrayIndex,布尔值已检查,BitArray-parentBitArray)
    {
    this.BitArrayIndex=BitArrayIndex;
    this.isChecked=isChecked;
    this.ParentBitArray=ParentBitArray;
    }
    公共场所被检查
    {
    get=>isChecked;
    设置
    {
    if(ParentBitArray!=null)
    {
    ParentBitArray[BitArrayIndex]=isChecked=value;
    OnPropertyChanged(名称(已检查));
    }
    }
    }
    私有void OnPropertyChanged([CallerMemberName]字符串propertyName=null)
    {
    PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(propertyName));
    }
    }
    /// 
    ///2.使用项目对象的可观察集合创建MVVM视图模型
    /// 
    /// 
    公共类BitArrayViewModel:INotifyPropertyChanged
    {
    专用只读位数组位数组;
    私人可观测收集项目;
    公共事件属性更改事件处理程序属性更改;
    公共可观测收集项目
    {
    获取=>项目;
    设置
    {
    项目=价值;
    OnPropertyChanged(项目名称);
    }
    }
    公共BitArrayViewModel(BitArray BitArray)
    {
    this.bitArray=bitArray;
    var query=this
    .位数组
    .Cast()
    .选择((s,i)=>新项(i,s,this.bitArray));
    this.Items=新的ObservableCollection(查询);
    }
    公共整数CountOnBits()
    {
    返回此.bitArray.Cast().Count(s=>s);
    }
    公共整数CountOffBits()
    {
    返回此.bitArray.Cast().Count(s=>!s);
    }
    受保护的虚拟void OnPropertyChanged([CallerMemberName]字符串propertyName=null)
    {
    PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(propertyName));
    }
    }
    /// 
    ///3.在代码隐藏中数据绑定视图模型
    /// 
    /// 
    /// 
    公共部分类主窗口:窗口
    {
    公共BitArrayViewModel视图模型;
    公共主窗口()
    {
    初始化组件();
    this.DataContext=ViewModel=new-BitArrayViewModel(new-BitArray(100));
    Show($“您有{ViewModel.CountOnBits()}开位和{ViewModel.CountOffBits()}关位”);
    }
    private void按钮base_OnClick(对象发送方,RoutedEventTarget e)
    {
    Show($“您有{ViewModel.CountOnBits()}开位和{ViewModel.CountOffBits()}关位”);
    }
    }
    }
    
    XAML

    
    绑定到位数组
    
    使用MVVM的好处是,您可以根据需要查看模型

  • 创建一个Item类来跟踪数组中每个位的状态
  • 使用项目对象的可观察集合创建MVVM视图模型
  • 在代码隐藏中数据绑定视图模型
  • 用绑定信息装饰您的xaml
  • 就这样!享受吧

    C#

    使用系统集合;
    使用System.Collections.ObjectModel;
    使用系统组件模型;
    使用System.Linq;
    使用System.Runtime.CompilerServices;
    使用System.Windows;
    命名空间数据绑定位数组
    {
    /// 
    ///1.创建一个Item类来跟踪数组中每个位的状态。
    /// 
    /// 
    公共类项目:INotifyPropertyChanged
    {
    公共事件属性更改事件处理程序属性更改;
    公共int位数组索引{get;set;}
    公共位数组ParentBitArray{get;set;}
    私人住宅被检查;
    公共项(int-bitArrayIndex,布尔值已检查,BitArray-parentBitArray)
    {
    this.BitArrayIndex=BitArrayIndex;
    
    using System.Collections;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Linq;
    using System.Runtime.CompilerServices;
    using System.Windows;
    
    namespace DataBindingBitArray
    {
    
        /// <summary>
        /// 1. Create an Item class to track the status of each bit in the array. 
        /// </summary>
        /// <seealso cref="System.ComponentModel.INotifyPropertyChanged" />
        public class Item : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
            public int BitArrayIndex { get; set; }
            public BitArray ParentBitArray { get; set; }
    
            private bool isChecked;
            public Item(int bitArrayIndex, bool isChecked, BitArray parentBitArray)
            {
                this.BitArrayIndex = bitArrayIndex;
                this.isChecked = isChecked;
                this.ParentBitArray = parentBitArray;
            }
            public bool IsChecked
            {
                get => isChecked;
                set
                {
                    if (ParentBitArray != null)
                    {
                        ParentBitArray[BitArrayIndex] = isChecked = value;
    
                        OnPropertyChanged(nameof(IsChecked));
                    }
                }
            }
            private void OnPropertyChanged([CallerMemberName] string propertyName = null)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    
        /// <summary>
        /// 2. Create a MVVM view model with an observable collection of your Item object
        /// </summary>
        /// <seealso cref="System.ComponentModel.INotifyPropertyChanged" />
        public class BitArrayViewModel : INotifyPropertyChanged
        {
            private readonly BitArray bitArray;
            private ObservableCollection<Item> items;
            public event PropertyChangedEventHandler PropertyChanged;
            public ObservableCollection<Item> Items
            {
                get => items;
                set
                {
                    items = value;
                    OnPropertyChanged(nameof(Items));
                }
            }
            public BitArrayViewModel(BitArray bitArray)
            {
                this.bitArray = bitArray;
    
                var query = this
                    .bitArray
                    .Cast<bool>()
                    .Select((s, i) => new Item(i, s, this.bitArray));
    
                this.Items = new ObservableCollection<Item>(query);
            }
    
            public int CountOnBits()
            {
                return this.bitArray.Cast<bool>().Count(s => s);
            }
            public int CountOffBits()
            {
                return this.bitArray.Cast<bool>().Count(s => !s);
            }
    
            protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    
        /// <summary>
        /// 3 . Databind your view model in code behind
        /// </summary>
        /// <seealso cref="System.Windows.Window" />
        /// <seealso cref="System.Windows.Markup.IComponentConnector" />
        public partial class MainWindow : Window
        {
            public BitArrayViewModel ViewModel;
    
            public MainWindow()
            {
                InitializeComponent();
    
                this.DataContext = ViewModel = new BitArrayViewModel(new BitArray(100));
    
                MessageBox.Show($"You have {ViewModel.CountOnBits()} on bits and {ViewModel.CountOffBits()} off bits");
            }
    
            private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
            {
                MessageBox.Show($"You have {ViewModel.CountOnBits()} on bits and {ViewModel.CountOffBits()} off bits");
            }
        }
    }
    
    <Window x:Class="DataBindingBitArray.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:DataBindingBitArray"
            mc:Ignorable="d"
            Height="360" Width="250">
        <StackPanel Height="300" Margin="10">
            <Label Height="40"  Margin="5" FontSize="18">Binding to Bit Array</Label>
            <ScrollViewer Height="200">
                <ItemsControl  Margin="5" x:Name="ItemsControl1" ItemsSource="{Binding Path=Items}"  HorizontalAlignment="Stretch">
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <CheckBox IsChecked="{Binding Path=IsChecked, Mode=TwoWay}" Content ="{Binding Path=BitArrayIndex }"/>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
            </ScrollViewer>
            <Button Height="40" Margin="5" Click="ButtonBase_OnClick" Content="Show BitArray Status"></Button>
        </StackPanel>
    </Window>