Мне очень нравится Caliburn и соглашение об именовании, и был удивлен, что Видимость не связана так же, как Конвенция CanNAME используется для защиты действия. Насколько я знаю, BooleanToVisibilityConverter используется только тогда, когда Binding явно используется в Caliburn, а не автоматически, как метод защиты. Поэтому я решил изменить источник, чтобы автоматически привязать его к "bool? ControlNameIsVisible()" (нулевой эквивалент коллапса) или тому подобное. Мне было интересно, если это правильный подход, и если су, если кто-то уже выполнил эту реализацию и мог бы поделиться ею здесь.
Видимость Автообязательность с соглашением об именах
Ответ 1
Вы можете использовать этот подход, если хотите, это совершенно разумно. Другой подход - использовать в вашей модели представления Border с тем же именем, что и логическое свойство. Caliburn.Micro установит видимость границы на основе значения логического свойства.
<Border x:Name="ControlIsVisible">
<TextBox x:Name="MyControl" ... />
</Border>
Ответ 2
Если вы хотите общее решение, это то, на чем я закончил, на основе: Добавление соглашения для IsEnabled на Caliburn.Micro
Обратите внимание на переопределение BindActions, а также BindProperties, чтобы вы могли проверять наличие видимости на вещах, у которых есть действия, связанные с ними.
protected override void Configure()
{
base.Configure();
ConventionManager.AddElementConvention<UIElement>(UIElement.VisibilityProperty, "Visibility", "VisibilityChanged");
var baseBindProperties = ViewModelBinder.BindProperties;
ViewModelBinder.BindProperties =
(frameWorkElements, viewModel) =>
{
BindVisiblityProperties(frameWorkElements, viewModel);
return baseBindProperties(frameWorkElements, viewModel);
};
// Need to override BindActions as well, as it called first and filters out anything it binds to before
// BindProperties is called.
var baseBindActions = ViewModelBinder.BindActions;
ViewModelBinder.BindActions =
(frameWorkElements, viewModel) =>
{
BindVisiblityProperties(frameWorkElements, viewModel);
return baseBindActions(frameWorkElements, viewModel);
};
}
void BindVisiblityProperties(IEnumerable<FrameworkElement> frameWorkElements, Type viewModel)
{
foreach (var frameworkElement in frameWorkElements)
{
var propertyName = frameworkElement.Name + "IsVisible";
var property = viewModel.GetPropertyCaseInsensitive(propertyName);
if (property != null)
{
var convention = ConventionManager
.GetElementConvention(typeof(FrameworkElement));
ConventionManager.SetBindingWithoutBindingOverwrite(
viewModel,
propertyName,
property,
frameworkElement,
convention,
convention.GetBindableProperty(frameworkElement));
}
}
}