Вам просто нужно использовать привязку с подключенным преобразователем, чтобы прочитать значение байта из модели представления, и ICommand
для переключения указанного бита c в байте:
ByteToBitConverter.cs
class ByteToBiteConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) =>
value is byte byteValue
&& int.TryParse(parameter.ToString(), out int bitPosition)
? new BitArray(new Byte[] {byteValue}).Get(bitPosition - 1)
: Binding.DoNothing;
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
=> throw new NotSupportedException();
}
ViewModel.cs
class ViewModel : INotifyPropertyChanged
{
private byte byteValue;
public byte ByteValue
{
get => this.byteValue;
set
{
this.byteValue = value;
OnPropertyChanged();
}
}
public ICommand ToggleBitCommand => new RelayCommand(ToggleBit);
public int BitCount { get; set; }
public ViewModel()
{
this.ByteValue = 128;
}
private void ToggleBit(object commandParameter)
{
if (!int.TryParse(commandParameter.ToString(), out int bitPosition))
{
return;
}
var bytes = new Byte[] { this.ByteValue };
var boolArray = new bool[this.BitCount];
var bits = new BitArray(bytes);
int toggleBitIndex = bitPosition - 1;
bits.Set(toggleBitIndex, !bits.Get(toggleBitIndex));
bytes = new Byte[1];
bits.CopyTo(bytes, 0);
this.ByteValue = bytes.FirstOrDefault();
}
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
RelayCommand.cs
(реализация взята из Документы Microsoft: ретрансляция журнала команд c)
public class RelayCommand : ICommand
{
#region Fields
readonly Action<object> _execute;
readonly Predicate<object> _canExecute;
#endregion // Fields
#region Constructors
public RelayCommand(Action<object> execute) : this(execute, null) { }
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute; _canExecute = canExecute;
}
#endregion // Constructors
#region ICommand Members
[DebuggerStepThrough]
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter) { _execute(parameter); }
#endregion // ICommand Members
}
MainWindow.xaml
<Window>
<Window.DataContext>
<ByteToBitByteConverter />
</Window.DataContext>
<Window.Resources>
<ViewModel />
</Window.Resources>
<StackPanel>
<!--
CommandParameter is the bit position.
Binding.Mode of IsChecked has to be explicitely set to BindingMode.OneWay
-->
<CheckBox x:Name="Bit0"
Command="{Binding ToggleBitCommand}"
CommandParameter="1"
IsChecked="{Biding ByteValue, Mode=OneWay, Converter={StaticResource ByteToBitConverter}, ConverterParameter=1}" />
<CheckBox x:Name="Bit1"
Command="{Binding ToggleBitCommand}"
CommandParameter="2"
IsChecked="{Biding ByteValue, Mode=OneWay, Converter={StaticResource ByteToBitConverter}, ConverterParameter=2}" />
<CheckBox x:Name="Bit2"
Command="{Binding ToggleBitCommand}"
CommandParameter="3"
IsChecked="{Biding ByteValue, Mode=OneWay, Converter={StaticResource ByteToBitConverter}, ConverterParameter=3}" />
<CheckBox x:Name="Bit3"
Command="{Binding ToggleBitCommand}"
CommandParameter="4"
IsChecked="{Biding ByteValue, Mode=OneWay, Converter={StaticResource ByteToBitConverter}, ConverterParameter=4}" />
<CheckBox x:Name="Bit4"
Command="{Binding ToggleBitCommand}"
CommandParameter="5"
IsChecked="{Biding ByteValue, Mode=OneWay, Converter={StaticResource ByteToBitConverter}, ConverterParameter=5}" />
<CheckBox x:Name="Bit5"
Command="{Binding ToggleBitCommand}"
CommandParameter="6"
IsChecked="{Biding ByteValue, Mode=OneWay, Converter={StaticResource ByteToBitConverter}, ConverterParameter=6}" />
<CheckBox x:Name="Bit6"
Command="{Binding ToggleBitCommand}"
CommandParameter="7"
IsChecked="{Biding ByteValue, Mode=OneWay, Converter={StaticResource ByteToBitConverter}, ConverterParameter=7}" />
<CheckBox x:Name="Bit7"
Command="{Binding ToggleBitCommand}"
CommandParameter="8"
IsChecked="{Biding ByteValue, Mode=OneWay, Converter={StaticResource ByteToBitConverter}, ConverterParameter=8}" />
</StackPanel>
</Window>