2011-07-09 45 views
16

我真的很喜欢Caliburn和命名约定绑定,并且很惊讶 可见性没有像使用“CanNAME”约定来保护动作一样。 据我所知,仅当在Caliburn中明确使用Binding时才使用BooleanToVisibilityConverter,而不是自动使用Guard方法。所以我想修改源代码以自动绑定到“bool?ControlNameIsVisible()”(null equals collapse)或类似的。我想知道这是否是正确的方法,如果有人已经完成实施并且可以在此分享。可见性使用命名约定的自动绑定

回答

17

如果你愿意,你可以使用这种方法,这是完全合理的。另一种方法是在视图模型上使用与名称相同的边框作为布尔属性。 Caliburn.Micro将根据布尔属性的值设置Border的可见性。

<Border x:Name="ControlIsVisible"> 
    <TextBox x:Name="MyControl" ... /> 
</Border> 
+0

很好地完成。它可能不是所有实例的“正确”解决方案,但这是一个很好的提示。 – IAmTimCorey

+0

对于那些不希望在UI上添加额外控件的人,可以直接将可见性绑定到该属性。这不会通过惯例自动绑定,但它所需的代码与上述大致相同,并且不需要额外的控制来进行换行。 – liang

+0

你有什么例子吗? –

9

如果你想有一个通用的解决方案,这是我结束了,基于:Adding a convention for IsEnabled to 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's 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)); 
      } 
     } 
    } 
+1

请注意,这不适用于Caliburn.Micro的深层属性绑定(例如Person_ControlName)。 – Govert

+0

这对于ToolBars来说非常有用。我可以在ToolBarTray中显示/隐藏整个工具栏,就像我可以在ToolBar中启用/禁用单个项目一样。非常好!到目前为止,没有问题。我使用Caliburn.Micro越多,Visual Studio就越不可思议。 – metaomniliquant