在WPF中使用另一個控件的值設置控件的數據綁定源是否有一種簡單而優雅的方式?使用複選框狀態來設置另一個控件的綁定源
例如,我有一個ListBox
顯示一組數據,當一個Checkbox
被選中時,我想使用另一組數據(例如過濾數據集)。
我可以看出,我可以將Checkbox
綁定到bool
屬性,並在數據源屬性的獲取器中工作,以便根據bool
值返回一個或另一個集合。但如果可能的話,我正在尋找更優雅的。
在WPF中使用另一個控件的值設置控件的數據綁定源是否有一種簡單而優雅的方式?使用複選框狀態來設置另一個控件的綁定源
例如,我有一個ListBox
顯示一組數據,當一個Checkbox
被選中時,我想使用另一組數據(例如過濾數據集)。
我可以看出,我可以將Checkbox
綁定到bool
屬性,並在數據源屬性的獲取器中工作,以便根據bool
值返回一個或另一個集合。但如果可能的話,我正在尋找更優雅的。
您可以將ListBox.ItemsSource
屬性綁定到CheckBox.IsChecked
屬性,並使用ValueConveter
檢查狀態,並返回適當的項目。
在此示例中,我使用MultiValueConveter
來允許從與Window
元素綁定的模型中選擇項目。
編輯:包含提供ItemSource
通知的示例方式。在Window.Resources
申報轉換器:
<Window.Resources>
<local:IsCheckedConverter x:Key="isCheckedConverter" />
</Window.Resources>
創建XAML
代碼:
<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();
}
}
創建conveter:
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));
}
}
}
綁定到MyModel對象有一個小缺點,即如果ListA或ListB屬性發生更改,則不會將這些更改通知給ItemsSource屬性Binding。也許,直接綁定到ListA和ListB屬性是有意義的。 –
由於列表是模型的成員,因此不是直接更新它們,而是通過模型進行更新。然後模型可以實現'INotifyPropertyChanged'接口。 –
問題是即使您的視圖模型實現INotifyPropertyChanged,如果綁定屬性不在綁定的路徑中,綁定也不會更新 –
您可以在複選框的
<CheckBox Name="myCheckBox" IsChecked="{Binding Path=Change}" />
在視圖模型的結合,然後定義屬性來處理複選框
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; }
的真/假條件如果你想做到這一點任務在XAML中,您可以創建DataTrigger綁定到CheckBox.IsChecked屬性和集合ItemsSource:
<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>
我可以計算出,我可以使得它返回一個或另一個數據源中的屬性的吸氣劑的複選框,一個布爾屬性,和工作結合根據布爾值設置。但如果可能的話,我正在尋找更優雅的。
好了,這在我看來:)
@Alex Russkov的建議是一個很好的選擇一個完美的解決方案。請注意,您需要將ListBox
的Tag
屬性綁定到的CheckBox
(而不是到CheckBox
本身)爲ItemsSource
屬性來獲取更新您檢查IsChecked
財產/取消選中CheckBox
:
<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>
實際上,如果DataTrigger綁定到Tag.IsChecked屬性,則存儲對整個CheckBox的引用的方法也應該可行。不過,我同意你的解決方案,綁定看起來更簡單:) –
@所有回答者:非常感謝所有答案!最後,我使用Krzysztof Bracha的MultipleBinding解決方案計算出我想要的結果。我甚至將ItemsSource放入多重綁定塊中,並使用轉換器根據複選框狀態設置輸出列表。它提供了一個簡單而優雅的解決方案(由我決定)。 –