У меня есть bool?
в моем ViewModel
, который связывается с двумя RadioButtons
в моем XAML.
Я бы хотел, чтобы для первого RadioButton's
IsChecked
было установлено значение True
, если свойство равно true
или null
, а для второго RadioButton
было установлено значение, обратное этому. Я просто не могу найти способ заставить это работать при обновлении свойства в ViewModel
.
Вот мой текущий XAML, который на самом деле не работает:
<RadioButton Name = "RadioButtonDhcpConfig" Grid.Row = "1" Grid.Column = "1" Content = "DHCP" VerticalAlignment = "Center" Margin = "5">
<RadioButton.Resources>
<Style TargetType = "RadioButton">
<Setter Property = "IsChecked" Value = "{Binding DhcpEnabled}"/>
<Style.Triggers>
<DataTrigger Binding = "{Binding DhcpEnabled}" Value = "{x:Null}">
<Setter Property = "IsChecked" Value = "True"/>
</DataTrigger>
</Style.Triggers>
</Style>
</RadioButton.Resources>
</RadioButton>
<!--Row 2-->
<RadioButton Name = "RadioButtonManualConfiguration" Grid.Row = "2" Grid.Column = "1" Content = "Manual Configuration:" VerticalAlignment = "Center" Margin = "5">
<RadioButton.Resources>
<Style TargetType = "RadioButton">
<Setter Property = "IsChecked" Value = "{Binding DhcpEnabled}"></Setter>
<Style.Triggers>
<DataTrigger Binding = "{Binding DhcpEnabled}" Value = "False">
<Setter Property = "IsChecked" Value = "True"></Setter>
</DataTrigger>
<DataTrigger Binding = "{Binding DhcpEnabled}" Value = "{x:Null}">
<Setter Property = "IsChecked" Value = "False"></Setter>
</DataTrigger>
<DataTrigger Binding = "{Binding DhcpEnabled}" Value = "True">
<Setter Property = "IsChecked" Value = "False"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</RadioButton.Resources>
</RadioButton>
Если я удалю все DataTriggers
из второго RadioButton
, установщик для DhcpEnabled
вызывается при щелчке по первому RadioButton
(как и ожидалось), но XAML над установщиком никогда не вызывается.
Проблема здесь в том, что мне нужно убедиться, что для моего свойства DhcpEnabled
установлено значение false
, когда пользователь щелкает второй RadioButton
и не может найти способ сделать это.
Любая помощь будет оценена.
@ Энди, разве для этого не потребовалось бы, чтобы я получил два разных свойства, по одному на RadioButton
? Что в конечном итоге также означало бы дополнительный код, чтобы гарантировать, что не существует сценария, в котором они либо ложны, либо оба истинны (хотя оба значения null в порядке).
Вместо этого попробуйте преобразователь, для первого преобразовать ноль в истину, а для второго создать инвертор, чтобы каждое ложное значение было истиной.
Вот конвертер для вашей первой кнопки:
public class Bool2NullConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null)
{
return value == null;
}
if (value is bool?)
{
return (value as bool?).Value;
}
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return value;
}
}
Затем вы могли бы использовать это в своем RadioButton
следующим образом: <RadioButton IsChecked = "{Binding DhcpEnabled, Converter = {StaticResource bool2Null}}">
Все, что вам нужно сделать сейчас, это изменить логику первого преобразователя, чтобы он стал инвертором, и применить его ко второму RadioButton
. Это также сделает XAML намного чище.
Это должно сработать. Для первой радиокнопки вы должны установить значение по умолчанию на true, а затем использовать триггер, чтобы изменить его, когда значение false. Для второго элемента управления вы просто привязываете его, чтобы он был противоположен первому элементу управления.
<RadioButton Name = "RadioButtonDhcpConfig" Grid.Row = "1" Grid.Column = "1" Content = "DHCP" VerticalAlignment = "Center" Margin = "5">
<RadioButton.Style>
<Style TargetType = "RadioButton">
<Setter Property = "IsChecked" Value = "True"/>
<Style.Triggers>
<DataTrigger Binding = "{Binding DhcpEnabled}" Value = "False">
<Setter Property = "IsChecked" Value = "False"/>
</DataTrigger>
</Style.Triggers>
</Style>
</RadioButton.Style>
</RadioButton>
<!--Row 2-->
<RadioButton Name = "RadioButtonManualConfiguration" Grid.Row = "2" Grid.Column = "1" Content = "Manual Configuration:" VerticalAlignment = "Center" Margin = "5">
<RadioButton.Style>
<Style TargetType = "RadioButton">
<Setter Property = "IsChecked" Value = "False"/>
<Style.Triggers>
<DataTrigger Binding = "{Binding ElementName=RadioButtonDhcpConfig, Path=IsChecked}" Value = "False">
<Setter Property = "IsChecked" Value = "True"/>
</DataTrigger>
</Style.Triggers>
</Style>
</RadioButton.Style>
</RadioButton>
Это не вызывает установщика DhcpEnabled
, который требуется.
Добавьте инвертированное свойство в модель просмотра (или используйте конвертер):
private bool? dhcpEnabled;
public bool? DhcpEnabled
{
get => dhcpEnabled;
set
{
if (dhcpEnabled != value)
{
dhcpEnabled = value;
OnPropertyChanged(nameof(DhcpEnabled));
OnPropertyChanged(nameof(DhcpDisabled));
}
}
}
public bool? DhcpDisabled
{
get => DhcpEnabled == false;
set => DhcpEnabled = !value;
}
Затем в XAML:
Обратите особое внимание на атрибут GroupName
.
<RadioButton x:Name = "RadioButtonDhcpConfig"
GroupName = "MyDhcp"
Grid.Row = "1" Grid.Column = "1" Content = "DHCP"
VerticalAlignment = "Center" Margin = "5"
IsChecked = "{Binding DhcpEnabled}"/>
<RadioButton x:Name = "RadioButtonManualConfiguration"
GroupName = "MyDhcp"
Grid.Row = "2" Grid.Column = "1"
Content = "Manual Configuration:"
VerticalAlignment = "Center" Margin = "5"
IsChecked = "{Binding DhcpDisabled}"/>
Это не вызывает установщика DhcpEnabled
Пожалуйста, смотрите обновление. Также рассмотрите возможность использования перечисления вместо логического значения, допускающего значение NULL.
На самом деле это все еще не работает. По несколько другой причине. DhcpDisabled
- это свойство SelectedNetworkAdapter
, которое пользователь может изменить. Радиокнопки обернуты вокруг Grid
, а его DataContext
установлен на SelectedNetworkAdapter
. Однако это означает, что если для DhcpDisabled
установлено значение True
, и я заменю SelectedNetworkAdapter
на что-то другое, у которого есть DhcpDisabled
как False
, будет вызван получатель DhcpDisabled
, изменится IsSelected
из RadioButtonManualConfiguration
, а вместе с ним будет вызван установщик DhcpDisabled
. снова.
Другими словами, это будет означать, что он будет называть DhcpEnabled = !value
, а value
- это false
, поэтому он установит DhcpEnabled
обратно на true
.
Если кнопки находятся в группе, то кнопка disable
ни к чему не должна быть привязана. Он просто сбросит первый, который автоматически установит для него значение false.
Вы думали о том, чтобы добавить эту логику в модель просмотра? Думаю, было бы более читабельно.