C# WPF IsEnabled с использованием нескольких Привязок?
у меня есть файл xaml WPF, описывающий раздел GUI, и я хотел бы, чтобы включение/отключение определенного элемента управления зависело от двух других. Код выглядит примерно так на данный момент:
<ComboBox Name="MyComboBox"
IsEnabled="{Binding ElementName=SomeCheckBox, Path=IsChecked}"/>
но я хотел бы, чтобы он зависел от другого флажка, а также что-то вроде:
<ComboBox Name="MyComboBox"
IsEnabled="{Binding ElementName=SomeCheckBox&AnotherCheckbox, Path=IsChecked}"/>
каков наилучший способ сделать это? Я не могу избавиться от чувства, что я упускаю что-то очевидное или иду по этому неправильному пути?
4 ответов
Я считаю, что вам, возможно, придется использовать MultiBinding с MultiValueConverter. Смотрите здесь: http://www.developingfor.net/wpf/multibinding-in-wpf.html
вот непосредственно связанный пример: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/5b9cd042-cacb-4aaa-9e17-2d615c44ee22
можно использовать MultiBinding
С преобразователем, который реализует IMultiValueConverter
.
только дать ответ вы можете (почти) скопировать и вставить:
статический ресурс нужен:
<converterNamespace:BooleanAndConverter x:Key="booleanAndConverter" />
ComboBox:
<ComboBox Name="MyComboBox">
<ComboBox.IsEnabled>
<MultiBinding Converter="{StaticResource booleanAndConverter}">
<Binding ElementName="SomeCheckBox" Path="IsChecked" />
<Binding ElementName="AnotherCheckbox" Path="IsChecked" />
</MultiBinding>
</ComboBox.IsEnabled>
</ComboBox>
код для конвертера:
namespace ConverterNamespace
{
public class BooleanAndConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
foreach (object value in values)
{
if ((value is bool) && (bool)value == false)
{
return false;
}
}
return true;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotSupportedException("BooleanAndConverter is a OneWay converter.");
}
}
}
вы также можете попробовать более короткую версию того же:
public class BooleanAndConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return values.OfType<IConvertible>().All(System.Convert.ToBoolean);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotSupportedException();
}
}
public class BooleanOrConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return values.OfType<IConvertible>().Any(System.Convert.ToBoolean);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotSupportedException();
}
}
и, конечно же, вам могут понадобиться преобразователи для видимости:
public class BooleanOrToVisibilityConverter : IMultiValueConverter
{
public Visibility HiddenVisibility { get; set; }
public bool IsInverted { get; set; }
public BooleanOrToVisibilityConverter()
{
HiddenVisibility = Visibility.Collapsed;
IsInverted = false;
}
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
bool flag = values.OfType<IConvertible>().Any(System.Convert.ToBoolean);
if (IsInverted) flag = !flag;
return flag ? Visibility.Visible : HiddenVisibility;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class BooleanAndToVisibilityConverter : IMultiValueConverter
{
public Visibility HiddenVisibility { get; set; }
public bool IsInverted { get; set; }
public BooleanAndToVisibilityConverter()
{
HiddenVisibility = Visibility.Collapsed;
IsInverted = false;
}
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
bool flag = values.OfType<IConvertible>().All(System.Convert.ToBoolean);
if (IsInverted) flag = !flag;
return flag ? Visibility.Visible : HiddenVisibility;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
как расширение ответа qqbenq:
добавлена функция для обработки Count
коллекции, например, если вы хотите проверить, если какой-то элемент ListView
выбран.
конвертер:
public class IsEnabledConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
foreach (var value in values)
{
switch (value)
{
case bool b when !b:
case int i when i == 0:
return false;
}
}
return true;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
return null;
}
}
пространство имен <theNamespace:IsEnabledConverter x:Key="IsEnabledConverter"/>
<Button x:Name="MyButton">
<Button.IsEnabled>
<MultiBinding Converter="{StaticResource IsEnabledConverter}">
<Binding ElementName="MyListView" Path="SelectedItems.Count"/>
<Binding ElementName="MyCheckBox" Path="IsChecked"/>
</MultiBinding>
</Button.IsEnabled>
</Button>