オブジェクトのプロパティとして数値を格納し、そのビットパターンをWindows Presentation Foundationのチェックボックスのシーケンスとして表示する方法を探していました。これは私が今使っているアプローチで、チェックボックスがチェックされたときに数値の更新があり、番号が変更されたときにチェックボックスが更新されます。これがより簡単な方法で達成できるかどうか教えてください。WPF:チェックボックスのビットフィールドとして数値を表示する方法
MainWindow.xaml.cs
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Media;
using System.Windows;
using System.Windows.Controls;
namespace WPF_Interface_Tests
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public BitField BF { get; set; }
public MainWindow()
{
InitializeComponent();
DataContext = this;
BF = new BitField(0, 32);
}
private void Plus_Click(object sender, RoutedEventArgs e)
{
if (BF.Value < uint.MaxValue)
BF.Value += 1;
}
private void Minus_Click(object sender, RoutedEventArgs e)
{
if (BF.Value > uint.MinValue)
BF.Value -= 1;
}
private void CheckBox_Click(object sender, RoutedEventArgs e)
{
SystemSounds.Beep.Play();
var a = (CheckBox)sender;
int checkity = 0;
if (a.IsChecked.Value)
checkity = 1;
BF.Value = BF.Value | (uint)(checkity << (int)a.Tag);
}
}
public class Bit : INotifyPropertyChanged
{
private bool state;
public bool State { get { return state; } set { if (this.state != value) { this.state = value; NotifyPropertyChanged("State"); } } }
public int Index { get; set; }
public Bit()
{
State = false;
Index = 0;
}
public event PropertyChangedEventHandler PropertyChanged; public void NotifyPropertyChanged(string propName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName)); }
}
public class BitField : INotifyPropertyChanged
{
private uint value;
public uint Value { get { return value; } set { if (this.value != value) { this.value = value; NotifyPropertyChanged("Value"); UpdateValues(); } } }
public byte ByteSize { get; set; }
public ObservableCollection<Bit> Values { get; set; }
public BitField(uint givenValue, byte givenByteSize)
{
Value = givenValue;
ByteSize = givenByteSize;
Values = new ObservableCollection<Bit>();
for (int i = 0; i < ByteSize; i++)
{
if ((Value | (uint)(1 << i)) == Value)
Values.Add(new Bit { State = true, Index = i });
else
Values.Add(new Bit { State = false, Index = i });
}
}
private void UpdateValues()
{
for (int i = 0; i < Values.Count; i++)
{
if ((Value | (uint)(1 << i)) == Value)
Values[i].State = true;
else
Values[i].State = false;
}
}
public event PropertyChangedEventHandler PropertyChanged; public void NotifyPropertyChanged(string propName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName)); }
}
}
MainWindow.xaml
<Window x:Class="WPF_Interface_Tests.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:WPF_Interface_Tests"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" Margin="10,201,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" Text="{Binding Path=BF.Value, UpdateSourceTrigger=PropertyChanged}"/>
<Button x:Name="Minus" Content="-" HorizontalAlignment="Left" Margin="10,229,0,0" VerticalAlignment="Top" Width="20" Click="Minus_Click" />
<ListBox x:Name="LBofChecks" HorizontalAlignment="Left" Height="186" Margin="10,10,0,0" VerticalAlignment="Top" Width="100" ItemsSource="{Binding Path=BF.Values, UpdateSourceTrigger=PropertyChanged}">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding Path=State, Mode=TwoWay}" Tag="{Binding Path=Index}" Click="CheckBox_Click"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button x:Name="Plus" Content="+" HorizontalAlignment="Left" Margin="35,229,0,0" VerticalAlignment="Top" Width="20" Click="Plus_Click" />
</Grid>
</Window>
マイアプローチメインウィンドウのプロパティとして新規BitField
オブジェクトを使用することを含みます。私はDataContext = this
を設定し、次にBitField
プロパティを構築します。
BitField
は、Value
プロパティが変更されたときに通知します。 Value
プロパティには、ビットシーケンスを表す数値が格納されます。チェックボックスにバインドするプロパティとして使用する値の一覧については、BitField
にObservableCollection<Bit> Values
というプロパティを付けます。 Bit
オブジェクトのコレクションには、それぞれのオブジェクトが変更されたときに通知されるオブジェクトもあります。また、Bit
のIndex
には、Bit
オブジェクトがObservableCollection<Bit> Values
の内部に格納されています。 .xamlファイルのCheckBox
テンプレートでは、チェックボックスのTag
プロパティをIndex
のBit
に関連付けていることがわかります。
おそらく簡単なアプローチはありますか?
各チェックボックスは特定のオプションを表します。もちろん、ビットとオプションは、数値表現に従って特定の方法で順序付けられます。オプションの意味を変えずに親コントロールのオプションの順序を変更するにはどうすればよいですか?新規オブジェクトを使用するか、チェックボックスオブジェクトを拡張するか、親コントロールの順序の代わりにチェックボックスのタグを使用する以外のアプローチはありますか?これらのオプションのうち、対応するビット位置を決定するには、チェックボックスのタグを使用します。 – Sparky
私はConvertBack()のために何をするだろうので、コンバータを使用しませんでしたか?ああ、どちらの状況でも既存の番号を使用する必要があります。気にしないで。 – Sparky