Привязка состояний флажков к BitArray в WPF - PullRequest
0 голосов
/ 03 мая 2018

В процессе изучения WFP я взялся за перенос некоторых старых приложений Winform в WPF и пытался придерживаться модели MVVM.

В приложении Winform у меня есть набор флажков, которые изменяют состояние BitArray, который, в свою очередь, отправляется по TCP. Простой материал.

Как бы я сделал это в WPF и привязке данных? Как я могу привязать определенный флажок к определенному биту в BitArray? Все примеры, которые я нашел для этой базы данных, связаны с одним логическим свойством в ВМ.

EDIT:

Я нашел решение здесь, используя ObservableCollection>:

Как связать ObservableCollection со списком флажков в 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;
}

Внутри класса-обёртки кто-нибудь может объяснить, что это делает и зачем это нужно?

1 Ответ

0 голосов
/ 04 мая 2018

Преимущество использования MVVM заключается в том, что вы можете выбирать модели для просмотра в соответствии с вашими потребностями.

  1. Создать класс Item для отслеживания состояния каждого бита в массиве.
  2. Создайте модель представления MVVM с наблюдаемой коллекцией вашего объекта Item
  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");
        }
    }
}

1026 * 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...