2012-04-07 4 views
4

私はMVVMアプリケーションを持っています。このアプリケーションには、ユーザー権限、表示/編集モード、およびオブジェクト状態に基づいていくつかの複雑なIsReadOnlyルールを含む複数のビューが含まれています。XAMLを使用してPanelやGroupBoxなどのコンテナ全体にIsReadOnly/IsEnabledを設定するにはどうすればよいですか?

Iは同じ容器(GroupBox/StackPanel/Grid/UserControl /等)のコントロールのグループ全体のためIsReadOnly及び/又はIsEnabledプロパティを設定したいです。このプロパティの値は、ViewModelで定義されます。

私は(TextBoxRadioButtonsComboBoxesといくつかのDataGridsなどの入力コントロールの数が多い)のUserControlあたり3-6異なるSomeGroupIsReadOnly性質を持っていると私は一般的な、MVVMやさしいソリューションを探しています、その意志バインディングを個々のコントロールごとに個別に指定するのではなく、コンテナごとに再利用することができます。

XAMLを使用してPanelまたはGroupBoxのようなコンテナ内のすべてのコントロールでIsReadOnly/IsEnabledを設定するにはどうすればよいですか?

... WPFは、箱から出して、これをサポートしていることを、私はコンテナ用でIsEnabledを設定すると、テキストボックスの重要な機能を無効にすることを言及するのを忘れてしまった

EDIT

いないようだ - というのその内容をコピーすることができます。私は彼らがIsReadOnly=true州にいる必要があります。そのための作業があれば、私の問題は解決されます。

+1

これは私が見つけた最良の解決策です:http://dkowalski.com/blog/archive/2010/02/04/readonly-wpf-containersaspx – surfen

答えて

6

私たちのためによく働いています何かがあなたのアプリケーション(以下私の例ではYourPermissionsViewModel)の許可構造を表すビューモデルを定義することです。

次に、任意のパネル(この例ではStackPanel)を拡張するカスタムパネルコントロールを作成できます。これにより、IsReadOnlyプロパティのバインディングを追加し、パネルの子に保持することができます。ここで

は、XAMLでのパネルは次のようになります:

<local:PanelExtension IsEnabled="{Binding YourPermissionsViewModel.IsEnabled}" 
         IsReadOnly="{Binding YourPermissionsViewModel.IsReadOnly}"> 
    <TextBox Text="eeny" Width="100" /> 
    <TextBox Text="meeny" Width="100"/> 
    <TextBox Text="miny" Width="100"/> 
    <TextBox Text="mo" Width="100" /> 
    <Label Content="coolio" Width="100" /> 
</local:PanelExtension> 

そして、ここでのStackPanel延長のStackPanelのすべての機能を含む制御ならびに任意に対応するプロパティ値を更新したカスタムIsReadOnlyの依存関係プロパティを取り付けていますその財産所有する子コントロール:あなたが必要として多くのカスタマイズされたプロパティを追加することができます。このアプローチでは

public class PanelExtension : StackPanel 
{ 
    public bool IsReadOnly 
    { 
     get { return (bool)GetValue(IsReadOnlyProperty); } 
     set { SetValue(IsReadOnlyProperty, value); } 
    } 
    public static readonly DependencyProperty IsReadOnlyProperty = 
     DependencyProperty.Register("IsReadOnly", typeof(bool), typeof(PanelExtension), 
     new PropertyMetadata(new PropertyChangedCallback(OnIsReadOnlyChanged))); 

    private static void OnIsReadOnlyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     ((PanelExtension)d).OnIsReadOnlyChanged(e); 
    } 

    protected virtual void OnIsReadOnlyChanged(DependencyPropertyChangedEventArgs e) 
    { 
     this.SetIsEnabledOfChildren(); 
    } 

    public PanelExtension() 
    { 
     this.Loaded += new RoutedEventHandler(PanelExtension_Loaded); 
    } 

    void PanelExtension_Loaded(object sender, RoutedEventArgs e) 
    { 
     this.SetIsEnabledOfChildren(); 
    } 

    private void SetIsEnabledOfChildren() 
    { 
     foreach (UIElement child in this.Children) 
     { 
      var readOnlyProperty = child.GetType().GetProperties().Where(prop => prop.Name.Equals("IsReadOnly")).FirstOrDefault(); 
      readOnlyProperty.SetValue(child, this.IsReadOnly, null); 
     } 
    } 
} 

は、それは本当にあなたに大きな柔軟性を貸すとを占めることができますさまざまな要素に対して複雑な権限を設定する必要がある場合に発生する多数のシナリオです。

+0

応答のおかげで、私は、 'YourPermissionsViewModel'。私はそれを試してみましょう。 – surfen

9

コントロールを含むパネルを無効にすると、パネル内のコントロールも無効になります。 PanelのIsEnabledメンバーをViewModelのboolプロパティにバインドし、ルールに従って設定して、Panelとそのすべての子を無効にします。

XAML:

<GroupBox IsEnabled="{Binding Path=IsGroupEnabled}"> 
    <StackPanel> 
     <Button Content="Sample Button"/> 
     <TextBox Text="Sample text box"/> 
    </StackPanel> 
</GroupBox> 
+2

+1はい、これは動作します。しかし、これによってTextBoxも無効になり、ユーザーは内容をコピーできなくなりました。 TextBoxを 'IsReadOnly = true'にしたいと思います。私は質問を編集しました。 – surfen

+0

私は反転ブール型コンバータを作成し、変換のためにIsGroupEnabled値を使ってTextBoxにバインドします。これはその上の良い投稿です:http://stackoverflow.com/questions/1039636/how-to-bind-inverse-boolean-properties-in-wpf – Xcalibur37

関連する問題