単純なデータを表示するオブジェクトエディタビューと、TemplateSelectorを使用してテンプレート化された値の解釈があります。生の値が更新されると、解釈された値も更新され、逆も同様です。単純なDataTemplateではうまくいきますが、値(ushort)がビットマップ(フラグのフィールド)を表すより複雑なシナリオがあります。このためにItemTemplateでItemsControlを使用します。これは、value-> flags方向では正常ですが、フラグがクリックされたときには機能しません。私はTemplateSelectorを使用したDataTemplateの双方向データバインディング
ビューのリソース... MVVMの世界にいるのでxaml.csファイル内のイベントに反応したくない:
<DataTemplate x:Key="StandardTemplate">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<TextBox Margin="0" VerticalAlignment="Top" Width="50" Text="{Binding Formatted,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="BitmapTemplate" >
<ItemsControl ItemsSource="{Binding Flags,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel HorizontalAlignment="Center" Width="20">
<TextBlock Text="{Binding BitPosition,Converter={StaticResource intConverter},ConverterParameter=1}" HorizontalAlignment="Center" />
<CheckBox HorizontalAlignment="Center" HorizontalContentAlignment="Center" IsChecked="{Binding IsBitSet,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
<selectors:EditTemplateSelector x:Key="EditSelector" BitmapTemplate="{StaticResource BitmapTemplate}" StandardTemplate="{StaticResource StandardTemplate}" />
それは、ビュー上で取得します。
<ContentPresenter Content="{Binding Register}" Grid.Row="2" Grid.ColumnSpan="2" Margin="10" ContentTemplateSelector="{StaticResource EditSelector}" />
public class BitmapBit : ObservableObject
{
ushort _bitPosition = 0;
bool _isSet = false;
public BitmapBit(ushort bitPos, bool isSet)
{
_bitPosition = bitPos;
_isSet = isSet;
}
public ushort BitPosition
{
get { return _bitPosition; }
set
{
if (_bitPosition == value)
return;
_bitPosition = value;
RaisePropertyChanged("BitPosition");
}
}
public bool IsBitSet
{
get { return _isSet; }
set
{
if (_isSet == value)
return;
_isSet = value;
RaisePropertyChanged("IsBitSet");
}
}
}
/// <summary>
/// A collection of BitmapBits
/// </summary>
public class Bitmap : ObservableCollection<BitmapBit>
{
const ushort NUMBER_OF_BITS = sizeof(ushort) * 8; // 8 BITS_IN_A_BYTE
protected Bitmap(ushort value) : base()
{
for (ushort i = 0; i < NUMBER_OF_BITS; ++i)
Insert(0, new BitmapBit(bitPos: i, isSet: (value & (1 << i)) != 0));
}
public static Bitmap Create(ushort value)
{
return new Bitmap(value);
}
public static ushort Parse(Bitmap bits)
{
ushort generated = 0;
foreach (BitmapBit bit in bits)
generated += (ushort)(bit.IsBitSet ? 2^bit.BitPosition : 0);
return generated;
}
}
IsBitSetセッターが呼び出されますが、私はこの問題はBitmaということだと思う:
私のビットマップとBitmapBitクラスがありますpはビットが変更されたという通知には関与していないので、フラグセッターは決して呼び出されません。 ObservableCollectionのメンバーが変更されたときにFlagsプロパティを更新/通知するにはどうすればよいですか?
ああ私はあなたが得ているものを見ています。私の編集はConverterの削除を反映しています。あなたが正しく指摘しているように混乱の層を追加しています。根底にある問題は今私が思うとはっきりしていますが、私はまだ解決策がありません! – AndyC
私の答えを編集しました – GazTheDestroyer
電球の瞬間!それは欠けていたリンクだった。ビットマップ構築ではビットマップを生成するオブジェクトが使用されるため、ビットが変更されたときにフラグを更新することができます。私を導いてくれてありがとう! – AndyC