Эта ошибка, связанная с тем, что вы получаете привязку к значению «Value», существует по причине, вы не можете обмануть ее значением «/ Value» и ожидать, что она исчезнет. Также есть много SO вопросов по этому поводу, хотя это может быть немного сложно найти и понять их без значительных усилий.
Чтобы ответить на ваш вопрос, я не знаю точных причин того, почему, но переключатели никогда не работали «из коробки» с WPF, предположительно потому, что существует слишком много разных способов, которыми людям нужно их подключать. вверх. В вашем случае вам нужно сделать две вещи:
1) Получите привязку OneWay от RadioProperty к работающей кнопке управления. Вы уже заметили, что параметры конвертера не могут использовать привязки, вместо этого можно использовать мультиконвертер:
public class RadioPropertyConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values == null)
return false;
if (values.Length != 2)
return false;
return Object.Equals(values[0], values[1]);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
Забудьте о ConvertBack
, в этом контексте это бессмысленно, и оно вам не понадобится. Вернувшись в свой XAML, вы теперь используете это в теге OneWay MultiBinding в RadioButton.IsChecked, передавая значение RadioProperty и текущее значение словаря:
<RadioButton.IsChecked>
<MultiBinding Converter="{StaticResource radioPropertyConverter}" Mode="OneWay">
<Binding Path="Value" />
<Binding Path="DataContext.Value" RelativeSource="{RelativeSource AncestorType={x:Type StackPanel}}" />
</MultiBinding>
</RadioButton.IsChecked>
2) Получите привязку, работающую в другом направлении, т. Е. Щелчок переключателей обновляет соответствующее значение RadioProperty. На самом деле есть несколько различных способов сделать это, но тот, который я предпочитаю, использует тот факт, что переключатели, как и все другие кнопки, генерируют команды при нажатии (что вы, очевидно, уже заметили, учитывая наличие пустой команды обработчик в теге <RadioButton>
). Все, что вам нужно сделать, это добавить привязку к обработчику команд в вашем классе RadioProperty и для передачи CommandParameter в значение Key для нажатой кнопки:
<RadioButton Content="{Binding Path=Key}"
Command="{Binding Path=DataContext.SetValueCommand, RelativeSource={RelativeSource AncestorType={x:Type StackPanel}}}"
CommandParameter="{Binding Key}">
А затем вы просто добавляете обработчик ICommand в ваш класс RadioProperty, который принимает ключ и использует его для установки обоих PropName и Value:
private ICommand _SetValueCommand;
public ICommand SetValueCommand => this._SetValueCommand ?? (this._SetValueCommand = new RelayCommand<string>(OnSetValue));
private void OnSetValue(string key)
{
this.PropName = key;
this.Value = this.Values[key];
}
Если у вас есть другие элементы управления, привязанные к тем же экземплярам RadioProperty, то вам также может потребоваться уведомить об изменении свойств PropName и Value, но в противном случае это должно работать нормально.