Связывание WPF:! Значение
У меня есть кнопка:
<Button Content="Stop loading" />
В ViewModel у меня есть свойство IsLoaded. Я не хочу писать свойство IsNotLoaded, но я хочу использовать IsLoaded в привязке и отключении кнопки, когда IsLoaded = true.
Как реализовать что-то вроде этого:
<Button Content="Stop loading" IsEnabled="{Binding !IsLoaded}" />
P.S. если это сложнее, чем писать дополнительное свойство, я буду использовать свойство IsNotLoaded.
Ответы
Ответ 1
В то время как ответы на все преобразователи действительны, вы можете захотеть взглянуть на альтернативную методологию: Commanding.
В WPF (и несколько в Silverlight) вы можете привязать ICommand к этой кнопке. Итак, если вы создали на свой ViewModel свойство, называемое CancelLoadingCommand, которое реализовало ICommand, вы бы связали кнопку следующим образом:
<Button Content="Stop Loading" Command="{Binding CancelLoadingCommand}" />
Реализация CancelLoadingCommand в вашей ViewModel будет выглядеть примерно так:
public ICommand CancelLoadingCommand
{
get
{
if (_cancelLoadingCommand== null)
{
this._cancelLoadingCommand= new RelayCommand(
delegate
{
// Cancel the loading process.
},
delegate
{
return !this.IsLoaded;
}
);
}
return _cancelLoadingCommand;
}
}
Обратите внимание: здесь я использую RelayCommand (который является частью инфраструктур PRISM или MVVM-Light). Я бы посоветовал посмотреть на один из них.
Надеюсь, это поможет.
Ответ 2
Стандартным средством для этого является создание IValueConverter
, которое инвертирует ваши логические значения. Хотя создание этого класса сложнее, чем добавление нового свойства, оно полностью повторно используется, поэтому позже вы можете повторно использовать его в других привязках (без загрязнения вашей модели ViewModel с множеством свойств свойств).
Этот класс будет выглядеть примерно так:
[ValueConversion(typeof(bool), typeof(bool))]
public class InvertBoolConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
bool booleanValue = (bool)value;
return !booleanValue;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
bool booleanValue = (bool)value;
return !booleanValue;
}
}
Затем вы добавите его в свои ресурсы:
<src:InvertBoolConverter x:Key="invertBoolConverter"/>
После этого вы будете использовать его как:
<Button Content="Stop loading"
IsEnabled="{Binding IsLoaded, Converter={StaticResource invertBoolConverter}}"
/>
Ответ 3
Одним из решений является использование конвертера для инвертирования логического значения. Что-то вроде
public class InvertedBoolenConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return !(bool)value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return !(bool)value;
}
}
Затем добавьте конвертер к ресурсу где-нибудь и используйте его в привязке:
<YourUserControl.Resources>
<c:InvertedBoolenConverter x:Key="InvertedBoolenConverter" />
</YourUserControl.Resources>
<Button Content="Stop loading" IsEnabled="{Binding IsLoaded,Converter={StaticResource InvertedBoolenConverter}}" />
Ответ 4
Вы хотите использовать конвертер. Вот то, что сделает трюк для вас.
public class booleaninverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return !(bool)value;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return !(bool)value;
}
}
Чтобы использовать его, напишите свой xaml так:
<Button Content="Stop loading" IsEnabled="{Binding IsLoaded, Converter={StaticResource booleaninverter}" />
Вы можете сделать статический ресурс в своем разделе App.xaml или других ресурсов окна/управления. Конечно, вы должны сделать "локальные" объявления пространства имен и что-нет, но это большая часть работы, проделанной для вас.
<local:booleaninverter x:key="booleaninverter"/>