Продолжая квест, начатый с моего предыдущего вопроса, я решил «динамизировать» все мои типы элементов управления, начиная с флажков. Я сделал что-то, где пользовательский элемент управления получает StackPanel, заполненный двумя экземплярами CheckBox, второй из которых виден только тогда, когда отмечен первый. Но проверка первого никогда не показывает второго, и происходит другое странное поведение.
РЕДАКТИРОВАНИЕ: Я только сейчас обнаружил, что ответ, который я принял на предыдущий вопрос, исчез! Прежде чем я перейду к DynamicSettingsGroupVM, вот еще один класс, который мне сказал потерянный ответчик:
Код: Выделить всё
public class DynamicSettings : INotifyPropertyChanged {
private readonly Dictionary _values = new();
public event PropertyChangedEventHandler? PropertyChanged;
public object? this[string key] {
get => _values.TryGetValue(key, out var v) ? v : null;
set {
_values[key] = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(key));
}
}
}
Код: Выделить всё
public partial class DynamicSettingsGroupVM : ViewModelBase {
[ObservableProperty]
private string _name;
public DynamicSettings DynamicSettingsProperties { get; } = new ();
public DynamicSettingsGroupVM(string aName) {
Name = aName;
((INotifyPropertyChanged)DynamicSettingsProperties).PropertyChanged +=
new PropertyChangedEventHandler(HandlePropertyChanges);
}
private void HandlePropertyChanges(
object? sender, PropertyChangedEventArgs e) {
Trace.WriteLine($"{e.PropertyName} has changed to {DynamicSettingsProperties[e.PropertyName]}.");
}
}
Код: Выделить всё
Код: Выделить всё
public void CreateDynamicCheckBoxes(string upperBoundProp, string lowerBoundProp) {
var myDC = DataContext as ViewModels.DynamicSettingsGroupVM;
var upperCB = new CheckBox {
[!CheckBox.IsCheckedProperty] = new Binding($"DynamicSettingsProperties[{upperBoundProp}]"),
Content = "Upper"
};
var lowerCB = new CheckBox {
[!CheckBox.IsCheckedProperty] = new Binding($"DynamicSettingsProperties[{lowerBoundProp}]"),
[!IsVisibleProperty] = new Binding($"DynamicSettingsProperties[{upperBoundProp}]"),
Content = "Lower, visible when Upper checked"
};
myDC.DynamicSettingsProperties[upperBoundProp] = false;
myDC.DynamicSettingsProperties[lowerBoundProp] = false;
stpDynamicFields.Children.Add(upperCB);
stpDynamicFields.Children.Add(lowerCB);
}
Код: Выделить всё
var dynaSettings = new DynamicSettingsGroup();
dynaSettings.DataContext = new DynamicSettingsGroupVM("New CheckBoxes!");
dynaSettings.CreateDynamicCheckBoxes("IsUpperChecked", "IsLowerChecked");
stpSettingsGroups.Children.Add(dynaSettings);
Код: Выделить всё
IsUpperChecked has changed to False.
IsLowerChecked has changed to False.

Когда я нажимаю флажок «Верхний», отлаживается следующее, но «Нижний...» не появляется:
Код: Выделить всё
IsUpperChecked has changed to True.
Попытка первого исправления
Я подумал, что, возможно, индексы привязок должны быть реальными строками, поскольку именно так к ним обращается другой код:
Код: Выделить всё
var upperCB = new CheckBox {
[!CheckBox.IsCheckedProperty] = new Binding($"DynamicSettingsProperties[\"{upperBoundProp}\"]"),
Content = "Upper"
};
var lowerCB = new CheckBox {
[!CheckBox.IsCheckedProperty] = new Binding($"DynamicSettingsProperties[\"{lowerBoundProp}\"]"),
[!IsVisibleProperty] = new Binding($"DynamicSettingsProperties[\"{upperBoundProp}\"]"),
Content = "Lower, visible when Upper checked"
};
Код: Выделить всё
IsUpperChecked has changed to False.
IsLowerChecked has changed to False.
[Binding]An error occurred binding 'IsVisible' to 'DynamicSettingsProperties["IsUpperChecked"]': 'Could not convert '(null)' (null) to 'System.Boolean'.' (CheckBox #2428637)

При первом щелчке по флажку выводится сообщение «изменено на ложное», а нижний флажок остается видимым, несмотря ни на что.
Попытка второго исправления
Я затем использовал фактический экземпляр Binding, чтобы я мог инициализировать его со значением по умолчанию и не начинать с нуля:
Код: Выделить всё
var lowerCB = new CheckBox {
[!CheckBox.IsCheckedProperty] = new Binding($"DynamicSettingsProperties[\"{lowerBoundProp}\"]"),
Content = "Lower, visible when Upper checked"
};
var visBinding = new Binding($"DynamicSettingsProperties[\"{upperBoundProp}\"]") {
TargetNullValue = false
};
lowerCB.Bind(IsVisibleProperty, visBinding);
Код: Выделить всё
IsUpperChecked has changed to False.
IsLowerChecked has changed to False.
"IsUpperChecked" has changed to False.
Попытка третьего исправления
Я удалил \" из аргументов инициализации привязки, а "Верхний" инициализировался с значением true непроверенное состояние, выводится только это:
Код: Выделить всё
IsUpperChecked has changed to False.
IsLowerChecked has changed to False.
Попытка четвертого исправления
Я также добавил нулевую защиту к привязке проверенного состояния «Верхнего»:
Код: Выделить всё
var upperCB = new CheckBox {
Content = "Upper"
};
var upperCheckBinding = new Binding($"DynamicSettingsProperties[{upperBoundProp}]") {
TargetNullValue = false,
Mode = BindingMode.TwoWay
};
upperCB.Bind(CheckBox.IsCheckedProperty, upperCheckBinding);
Всякая помощь в работе привязки IsVisible приветствуется, спасибо.