Флажок привязки WPF IsChecked к другим флажкам (IsChecked//!Свойства isenabled)
У меня есть флажок "все", который я хотел бы привязать к (IsChecked//!IsEnabled) других флажков.
проверка " все " проверяет все включенные флажки.
снимите флажок " все " снимите все флажки.
ручная проверка каждого включенного флажка будет проверять "все".
когда все включенные флажки и " все "отмечены и пользователь снимает любой флажок, "все" автоматически снимает.
Я новичок в привязке данных WPF. Я думал, может быть, я просто управляю щелчком "все", чтобы установить другие флажки. Но я не знаю, как привязаться к обоим свойствам нескольких источников. Когда я нажимаю " все "и вручную снимаю другой флажок," все " должно быть снято.
2 ответов
вот способ сделать это в Xaml с конвертерами. Это предполагает, что все ваши флажки добавляются непосредственно в качестве элементов управления в Xaml (это не очень динамично, не будет работать для DataTemplate и т. д.). Сначала мы создаем три флажка (CheckBox1, CheckBox2, CheckBox3), которые будут проверены/сняты при проверке CheckAllCheckBox. Он также будет работать в обратном направлении.
обновление
Последняя часть (игнорировать отключенный флажок) была немного проблемой здесь, и я не сумасшедший об этом решении, но я не вижу лучшего способа. Мы храним значения из Convert и повторно используем их в ConvertBack для отключенного флажка. Делая это, мы также должны добавить атрибут x:Shared="False" для CheckAllConverter, так как новый экземпляр требуется для каждой Многосвязки, которая будет его использовать (маловероятно в этом случае, но все же..)
<Window.Resources>
<local:CheckAllConverter x:Key="CheckAllConverter" x:Shared="False"/>
</Window.Resources>
<StackPanel>
<CheckBox Content="Check All"
Name="CheckAllCheckBox">
<CheckBox.IsChecked>
<MultiBinding Converter="{StaticResource CheckAllConverter}">
<Binding ElementName="CheckBox1" Path="IsChecked" />
<Binding ElementName="CheckBox1" Path="IsEnabled" Mode="OneWay"/>
<Binding ElementName="CheckBox2" Path="IsChecked" />
<Binding ElementName="CheckBox2" Path="IsEnabled" Mode="OneWay"/>
<Binding ElementName="CheckBox3" Path="IsChecked" />
<Binding ElementName="CheckBox3" Path="IsEnabled" Mode="OneWay"/>
</MultiBinding>
</CheckBox.IsChecked>
</CheckBox>
<CheckBox Content="CheckBox 1"
Name="CheckBox1"/>
<CheckBox Content="CheckBox 2"
Name="CheckBox2"/>
<CheckBox Content="CheckBox 3"
Name="CheckBox3"/>
</StackPanel>
конвертер для CheckAll
public class CheckAllConverter : IMultiValueConverter
{
private object[] convertValues = null;
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
convertValues = new object[values.Length];
for(int i = 0; i < values.Length; i++)
{
convertValues[i] = values[i];
}
for (int i = 0; i < values.Length; i += 2)
{
bool isChecked = (bool)values[i];
bool isEnabled = (bool)values[i + 1];
if (isEnabled == false)
{
continue;
}
if (isChecked == false)
{
return false;
}
}
return true;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
object[] values = new object[targetTypes.Length];
for (int i = 0; i < values.Length; i += 2)
{
if (convertValues != null && (bool)convertValues[i + 1] == false)
{
values[i] = convertValues[i];
}
else
{
values[i] = value;
}
// IsEnabled is OneWay and won't care about this value
values[i + 1] = null;
}
return values;
}
}
Я бы создал ViewModel за вашим классом View, используя шаблон дизайна MVVM:http://msdn.microsoft.com/en-us/magazine/dd419663.aspx
затем на вашей ViewModel (которая должна будет реализовать INotifyPropertyChanged) вы можете иметь несколько bool
свойства, один для каждого флажка и другой для всех из них:
public bool IsChecked1
{
get
{
return isChecked1;
}
set
{
if (isChecked1 != value)
{
isChecked1 = value;
RaisePropertyChanged("IsChecked1");
RaisePropertyChanged("AreAllChecked");
}
}
}
// And so on
public bool AreAllChecked
{
get
{
return IsChecked1 && IsChecked2; // etc.
}
set
{
if (AreAllChecked != value)
{
IsChecked1 = value;
IsChecked2 = value;
// etc.
}
}
}