2011-07-09 9 views
16

私はCaliburnと命名規則バインディングが本当に好きです。 「CanNAME」条約がアクションをガードするために使用されているのと同じ方法でVisibilityがバインドされていないことに驚いています。 私が知る限り、Bindingが明示的にCaliburnで使用され、自動的にガードメソッドに似ていない場合にのみ使用されるBooleanToVisibilityConverterがあります。だから、私は自動的にバインドするソースを "bool?ControlNameIsVisible()"(nullは崩壊に等しい)またはそれに類するものに変更することを考えていました。誰かがすでに実装を行っていて、ここでそれを共有できるなら、それが適切なアプローチであるかどうかというと私は思っていました。可視性命名規則付き自動バインディング

答えて

17

あなたが望むなら、あなたはこのアプローチを使うことができます、それは完全に合理的です。もう1つの方法は、ビューモデルのブール値プロパティと同じ名前のボーダーを使用することです。 Caliburn.Microは、booleanプロパティの値に基づいて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ですばらしく機能します。 ToolBarの個々の項目を有効/無効にするのと同じ方法で、ToolBarTrayにツールバー全体を表示/非表示することができます。非常に素晴らしい!これまでのところ、問題はありません。 Caliburn.Microを使用するほど、Visual Studioの使用率は低くなります。 – metaomniliquant