4

我有一个MVVM包含多个视图的应用程序,其中包含一些IsReadOnly基于用户权限、查看/编辑模式和对象状态的复杂规则。

我想为同一个容器( ////等)中的整个控件组设置和/IsReadOnly或属性。此属性的值将在 ViewModel 中定义。IsEnabledGroupBoxStackPanelGridUserControl

SomeGroupIsReadOnly每个 UserControl 有 3-6 个不同的属性(有大量的输入控件,比如,TextBox和some ),我正在寻找一个通用的、友好的解决方案,这将允许我在每个容器的基础上重用绑定,而不是分别为每个单独的控件指定它们。RadioButtonsComboBoxesDataGridsMVVM

如何使用 XAML 在 Panel 或 GroupBox 等容器内的所有控件上设置 IsReadOnly / IsEnabled?

似乎 WPF 不支持开箱即用...

编辑

我忘了提到为容器设置 IsEnabled 会禁用 TextBoxes 的一个重要特性——能够复制它们的内容。我需要他们处于IsReadOnly=true状态。如果有解决方法,那么我的问题将得到解决。

4

2 回答 2

9

禁用包含您的控件的面板也将禁用面板内的控件。将 Panel 的 IsEnabled 成员绑定到 ViewModel 上的 bool 属性,并根据您的规则设置它以禁用 Panel 及其所有子项。

xml:

<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 回答