4

ユーザー権限、ビュー/編集モード、およびオブジェクトの状態に基づくいくつかの複雑なルールを持つMVVM複数のビューを含むアプリケーションがあります。IsReadOnly

同じコンテナー ( / / / / など)内のコントロールのグループ全体のプロパティを設定IsReadOnlyしたいと思います。このプロパティの値は ViewModel で定義されます。IsEnabledGroupBoxStackPanelGridUserControl

UserControl ごとに 3 ~ 6 個の異なるプロパティ ( 、、および someSomeGroupIsReadOnlyなどの多数の入力コントロールを含む) があり、コンテナごとに Binding を再利用できる汎用的で使いやすいソリューションを探しています。 、個々のコントロールごとに個別に指定する代わりに。TextBoxRadioButtonsComboBoxesDataGridsMVVM

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

WPFがこれをそのままサポートしているようには見えません...

編集

コンテナに IsEnabled を設定すると、TextBox の重要な機能であるコンテンツのコピーが無効になることを忘れていました。私は彼らがIsReadOnly=true州にいる必要があります。そのための回避策があれば、私の問題は解決されます。

4

2 に答える 2

9

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

Xaml:

<GroupBox IsEnabled="{Binding Path=IsGroupEnabled}">
    <StackPanel>
        <Button Content="Sample Button"/>
        <TextBox Text="Sample text box"/>
    </StackPanel>
</GroupBox>
于 2012-04-07T03:55:11.703 に答える
7

私たちにとってうまくいったことは、アプリケーションの権限構造を表すビュー モデル (以下の例では 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);
        }
    }
}

このアプローチを使用すると、カスタマイズされたプロパティを必要な数だけ追加できます。これにより、柔軟性が大幅に向上し、さまざまな要素に複雑なアクセス許可を設定する必要がある場合に遭遇する可能性のある多数のシナリオに対応できます。

于 2012-04-07T04:38:05.180 に答える