コードを詳しく調べないと、あなたが何をしようとしているのか正確にはわかりませんが、私はあなたのシナリオについて漠然とした考えを持っていると思います。私はあなたのために例を作成し、これに似たものを示しています。Window
デモンストレーションを容易にするために、新しいコントロールを作成するのではなく、すべてのコードを1つにまとめました。手始めに、ウィンドウのXAMLを見てみましょう。
<Window x:Class="TestWpfApplication.DataBoundFlags"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TestWpfApplication"
Title="DataBoundFlags" Height="300" Width="300"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ListBox ItemsSource="{Binding AvailableOptions}" Grid.Row="0">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding}" CommandParameter="{Binding}"
Command="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type Window}}, Path=SelectCommand}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<TextBlock Text="{Binding SelectedOptions}" Grid.Row="1"/>
</Grid>
ウィンドウDataContext
は独自の分離コードに設定されているので、そこでプロパティにバインドできます。私はいくつかのプロパティを持ってAvailableOptions
います-あなたが選ぶことができるすべてのオプションです。SelectedOptions
ユーザーが現在選択しているオプションです。SelectCommand
はRelayCommand
、フラグを追加SelectedOptions
または削除するために使用されます。
XAMLの残りの部分は非常に単純である必要があります。はListBox
使用可能なすべてのオプションにバインドされ、各オプションは単一のとして表されますCheckBox
。CommandParameter
オプションアイテム自体にバインドされている、に注意してください。それでは、魔法が発生するコードビハインドを見てみましょう。
[Flags()]
public enum Options
{
Plain = 0,
Ketchup = 1,
Mustard = 2,
Mayo = 4,
HotSauce = 8
}
public partial class DataBoundFlags : Window
{
public static readonly DependencyProperty SelectedOptionsProperty =
DependencyProperty.Register("SelectedOptions", typeof(Options), typeof(DataBoundFlags));
public Options SelectedOptions
{
get { return (Options)GetValue(SelectedOptionsProperty); }
set { SetValue(SelectedOptionsProperty, value); }
}
public List<Options> AvailableOptions
{
get
{
return new List<Options>()
{
Options.Ketchup,
Options.Mustard,
Options.Mayo,
Options.HotSauce
};
}
}
public ICommand SelectCommand
{
get;
private set;
}
/// <summary>
/// If the option is selected, unselect it.
/// Otherwise, select it.
/// </summary>
private void OnSelect(Options option)
{
if ((SelectedOptions & option) == option)
SelectedOptions = SelectedOptions & ~option;
else
SelectedOptions |= option;
}
public DataBoundFlags()
{
SelectCommand = new RelayCommand((o) => OnSelect((Options)o));
InitializeComponent();
}
}
上から始めて、列挙型宣言、SelectedOptions
依存関係プロパティ、およびAvailableOptions
プロパティ(変更されないため、標準のCLRプロパティにすることができます)が続きます。次に、コマンドと、コマンドに対して実行されるハンドラー(オプションがオンまたはオフの場合)があります。まず、コマンドがどのように接続されているかに注目してください。新しいコマンドを作成しRelayCommand
て実行するようにOnSelect
指示し、コマンドパラメータを渡します。これは、XAMLでバインドされたのと同じコマンドパラメーターであることに注意してください。つまり、現在チェックされているオプションまたはチェックされていないオプションです。SelectedOptions
そのオプションをビット演算子の使用と比較します。オプションが存在する場合、それはチェックを外していることを意味し、ビットごとのANDを使用してそれをクリアする必要があります。存在しない場合は、ビットごとのORを使用して選択済みに追加します。
その場合、SelectedOptions
依存関係プロパティが自動的に更新さTextBlock
れ、XAMLのバインディングが更新されます。最終結果は次のとおりです。