2017-06-16 13 views
1

WPFでは、別のコントロールの値を使用してコントロールのデータバインディングソースを設定する簡単で洗練された方法はありますか?チェックボックスの状態を使用して、別のコントロールのバインディングソースを設定します。

たとえば、ListBoxには一連のデータが表示され、Checkboxにチェックを付けると、別のデータセット(たとえば、フィルタリングされたデータセットなど)を使用したいと考えています。

プロパティをboolプロパティにバインドし、bool値に応じて1つまたは別のセットを返すようにデータソースプロパティのゲッターで作業することができます。しかし、私はそれが可能であれば、さらにエレガントなものを探しています。

+0

@すべての回答:ありがとう、すべての答えのために!最後に、Krzysztof BrachaのMultipleBindingソリューションを使用して欲しいものを探し出しました。私は複数のバインディングブロック内にItemsSourceを配置し、チェックボックスの状態に応じて出力リストを設定するコンバータを使用します。シンプルで洗練されたソリューションを提供します(私にとって)。 –

答えて

1

あなたはCheckBox.IsCheckedプロパティにごListBox.ItemsSourceプロパティをバインドし、状態を確認し、適切な項目を返すためにValueConveterを使用することができます。

この例では、要素にバインドされたモデルからアイテムを選択するために、MultiValueConveterを使用します。

ItemSourceの通知を提供する方法の例が含まれています。 Window.Resources

宣言コンバータ:

<CheckBox Name="CheckBox" /> 
<ListBox> 
    <ListBox.ItemsSource> 
     <MultiBinding Converter="{StaticResource isCheckedConverter}"> 
      <Binding ElementName="CheckBox" Path="IsChecked"/> 
      <Binding Path="MyModel.MyLists" RelativeSource="{RelativeSource AncestorType={x:Type Window}}" /> 
     </MultiBinding> 
    </ListBox.ItemsSource> 
</ListBox> 

Window作成:

public partial class MainWindow : Window 
{ 
    public MyModel MyModel { get; set; } 

    public MainWindow() 
    { 
     InitializeComponent(); 

     MyModel = new MyModel(); 
    } 
} 

は最速を作成

<Window.Resources> 
    <local:IsCheckedConverter x:Key="isCheckedConverter" /> 
</Window.Resources> 

XAMLコードを作成します

public class IsCheckedConverter : IMultiValueConverter 
{ 
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     bool isChecked = (bool)values[0]; 
     List<string>[] lists = (List<string>[])values[1]; 

     if (isChecked == true) 
     { 
      return lists[0]; 
     } 
     else 
     { 
      return lists[1]; 
     } 

    } 

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

例モデルの実装:

public class MyModel : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 
    public List<string>[] MyLists { get; set; } 

    public MyModel() 
    { 
     MyLists = new List<string>[2]; 

     MyLists[0] = new List<string>() { "abc", "def", "ghi" }; 
     MyLists[1] = new List<string>() { "123", "456", "789" }; 
    } 

    public void UpdateListsExample() 
    { 
     MyLists[0] = new List<string>() { "abc", "def", "ghi", "jkl" }; 
     MyLists[1] = new List<string>() { "123", "456" }; 
     NotifyPropertyChanged("MyLists"); 
    } 

    private void NotifyPropertyChanged(String propertyName) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 
+0

MyModelオブジェクトへのバインドには、ListAプロパティまたはListBプロパティが変更された場合、ItemsSourceプロパティBindingにこれらの変更が通知されないという事実に関連する小さな欠点があります。おそらく、ListAプロパティとListBプロパティに直接バインドするのが理にかなっています。 –

+0

リストはモデルのメンバーであるため、モデルを直接更新するのではなく、モデルを更新することが理にかなっています。このモデルは、 'INotifyPropertyChanged'インタフェースを実装することができます。 –

+0

ビューモデルがINotifyPropertyChangedを実装していても、バインドされたプロパティがBindingのパスにない場合、バインディングは更新されません。 –

-1

あなたは、チェックボックスの結合

<CheckBox Name="myCheckBox" IsChecked="{Binding Path=Change}" /> 

でプロパティを定義することができますし、これを実現したい場合は、その後のviewmodelにチェックボックス

private bool isCheckedChange = false; 

public bool Change { 
    get { return isCheckedChange; } 
    set { 
     if (isCheckedChange) 
     { 
      MyListBocValue = new List<string> { "String1", "String2" }; 
     }else{ 
      MyListBocValue = new List<string> { "String3", "String4" }; 
     } 
    } 
} 

public List<String> MyListBocValue { get; set; } 
1

の真/偽条件を処理するために、 XAMLのタスクでは、を作成できます。CheckBox.IsCheckedプロパティにバインドし、ItemsSourceにバインドするDataTriggerを作成できます。

<Window.Resources> 
    <Style TargetType="ListBox" x:Key="listBoxStyle"> 
     <Setter Property="ItemsSource" Value="{Binding Source1}"/> 
     <Style.Triggers> 
      <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Tag.IsChecked}" Value="True"> 
       <Setter Property="ItemsSource" Value="{Binding Source2}"/> 
      </DataTrigger> 
     </Style.Triggers> 
    </Style> 
</Window.Resources> 
<Grid> 
    <CheckBox VerticalAlignment="Top" Name="checkBox"/> 
    <ListBox Margin="0,20,0,0" Tag="{Binding ElementName=checkBox}" Style="{StaticResource listBoxStyle}"/> 
</Grid> 
1

私はブール値プロパティにチェックボックスをバインドすることができることを把握し、それが1つまたは別のものを返すようにデータソースプロパティのゲッターで作業することができますboolの値に応じて設定します。しかし、私はそれが可能であれば、さらにエレガントなものを探しています。

まあ、これは私の意見でエレガントなソリューションです:)

@Alex Russkovの提案は良い選択肢です。あなたがチェックとしてItemsSourceプロパティが更新取得するためCheckBoxのチェックを外す/あなたはCheckBox(とないCheckBox自体に)のIsCheckedプロパティにListBoxTagプロパティをバインドする必要があることに注意してください。

<CheckBox x:Name="ckh" Content="Check Box..."/> 
<ListBox Tag="{Binding Path=IsChecked, ElementName=ckh}"> 
    <ListBox.Style> 
     <Style TargetType="ListBox"> 
      <Setter Property="ItemsSource" Value="{Binding SourceCollectionA}"/> 
      <Style.Triggers> 
       <Trigger Property="Tag" Value="True"> 
        <Setter Property="ItemsSource" Value="{Binding SourceCollectionB}"/> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 
    </ListBox.Style> 
</ListBox> 
+0

実際、DataTriggerがTag.IsCheckedプロパティにバインドされている場合、CheckBox全体への参照を格納する方法も有効です。しかし、あなたのソリューションでは、バインディングがよりシンプルに見えることに同意します:) –

関連する問題