-->

如何像面板或分组框中使用XAML对整个容器设置IsReadOnly /的IsEnabled?(How

2019-09-16 09:26发布

我有一个MVVM包含与一些复杂的多个视图应用IsReadOnly根据用户权限,查看/编辑模式和对象状态规则。

我想设置IsReadOnly和/或IsEnabled属性在同一容器(的总体进行控制组GroupBox / StackPanel / Grid / UserControl /等)。 此属性的值将在视图模型中定义。

我有3-6不同SomeGroupIsReadOnly每用户控件的属性(有大量像输入控件的TextBoxRadioButtonsComboBoxes和一些DataGrids )和我在寻找一个通用的, MVVM -友好的解决方案,这将让我重用上容器为单位绑定代替单独指定它们每个单独的控制。

如何设置IsReadOnly /的IsEnabled使用XAML像面板或分组框里面容器中的所有控件?

它似乎并不认为WPF支持这种开箱即用...

编辑

我忘了提,设定的IsEnabled的容器禁用文本框的一个重要特征 - 能复制他们的内容。 我需要他们在IsReadOnly=true状态。 如果有应该是一个workarond,那么我的问题将得到解决。

Answer 1:

是的运作良好的我们的东西是定义一个代表你的应用程序(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中的功能以及连接上任何子控件更新相应的属性值的自定义IsReadOnly依赖项属性的StackPanel的扩展控制谁拥有该属性:

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);
        }
    }
}

通过这种方法,你可以添加尽可能多的自定义的属性,你需要,它真的借给你的具有很大的灵活性,使您能够占到场景众多,当你需要设置各种要素的复杂的权限,你可能会遇到的问题。



Answer 2:

禁用包含您的控制也将关闭面板内的控制面板。 小组成员的IsEnabled绑定到你的视图模型一个布尔值属性,并根据您的规则禁用面板及其所有儿童的设置。

XAML:

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


文章来源: How to set IsReadOnly / IsEnabled on entire container like Panel or GroupBox using XAML?