簡體   English   中英

將復選框綁定到WPF中的BitArray

[英]Binding checkboxes states to a BitArray in WPF

在嘗試學習WFP的過程中,我承擔了將一些舊Winform應用程序移植到WPF中並嘗試堅持MVVM模型的任務。

在Winform應用程序中,我有一組復選框可以更改BitArray的狀態,這些狀態又可以通過TCP發送。 簡單的東西。

我將如何在WPF和數據綁定中執行此操作? 如何將特定復選框綁定到BitArray中的特定位? 我發現的所有將此數據綁定到VM中單個布爾屬性的示例。

編輯:

我在這里通過使用ObservableCollection>找到了解決方案:

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

我不明白的目的是:

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;
}

在包裝器類內部,有人可以解釋它的作用以及為什么需要它嗎?

使用MVVM的好處是您可以根據自己的需要選擇視圖模型。

  1. 創建一個Item類以跟蹤數組中每個位的狀態。
  2. 使用您的Item對象的可觀察集合創建MVVM視圖模型
  3. 在后面的代碼中將視圖模型數據綁定
  4. 用綁定信息裝飾您的XAML

而已! 請享用!

查看截圖

在GitHub上下載完整示例

C#

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");
        }
    }
}

XAML

<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>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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