2012-03-28 10 views
2

単純なデータを表示するオブジェクトエディタビューと、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プロパティを更新/通知するにはどうすればよいですか?

答えて

1

これは、あなたのチェックボックスがコンバータで作成されたBitmapBitオブジェクトを更新しているためです。彼らはあなたのItemsControlによって別々に呼び出されたコンバータ自体については何も知らない。

元のUshortを更新する場合は、実際にコンバータを経由するのではなく、ViewModelから直接BitmapBitコレクションを公開したいと考えています。そうすれば、BitmapBitオブジェクトのVM参照を更新し、BitmapBitセッターのushortを更新することができます。

編集: あなたの編集では少しクリアされていますが、まだ問題はほとんど解決しています。 BitmapBitsは基礎となるビットマップを認識していないので、更新しないでください。

あなたのFlagsがどのように定義されているかはわかりませんので、私はあなたにそれを更新する方法を示すことはできませんが、基本的には、Viewと同じように各BitmapBitの変更を監視するだけで、PropertyChanged :

protected Bitmap(ushort value) : base() 
{ 
    for (ushort i = 0; i < NUMBER_OF_BITS; ++i) 
    { 
     var bit = new BitmapBit(bitPos: i, isSet: (value & (1 << i)) != 0); 
     bit.PropertyChanged += (s, e) => UpdateFlags(); 
     Insert(0, bit); 
    } 
} 
+0

ああ私はあなたが得ているものを見ています。私の編集はConverterの削除を反映しています。あなたが正しく指摘しているように混乱の層を追加しています。根底にある問題は今私が思うとはっきりしていますが、私はまだ解決策がありません! – AndyC

+0

私の答えを編集しました – GazTheDestroyer

+0

電球の瞬間!それは欠けていたリンクだった。ビットマップ構築ではビットマップを生成するオブジェクトが使用されるため、ビットが変更されたときにフラグを更新することができます。私を導いてくれてありがとう! – AndyC

関連する問題