我有一个MVVM
包含与一些复杂的多个视图应用IsReadOnly
根据用户权限,查看/编辑模式和对象状态规则。
我想设置IsReadOnly
和/或IsEnabled
属性在同一容器(的总体进行控制组GroupBox
/ StackPanel
/ Grid
/ UserControl
/等)。 此属性的值将在视图模型中定义。
我有3-6不同SomeGroupIsReadOnly
每用户控件的属性(有大量像输入控件的TextBox
, RadioButtons
, ComboBoxes
和一些DataGrids
)和我在寻找一个通用的, MVVM
-友好的解决方案,这将让我重用上容器为单位绑定代替单独指定它们每个单独的控制。
如何设置IsReadOnly /的IsEnabled使用XAML像面板或分组框里面容器中的所有控件?
它似乎并不认为WPF支持这种开箱即用...
编辑
我忘了提,设定的IsEnabled的容器禁用文本框的一个重要特征 - 能复制他们的内容。 我需要他们在IsReadOnly=true
状态。 如果有应该是一个workarond,那么我的问题将得到解决。
是的运作良好的我们的东西是定义一个代表你的应用程序(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);
}
}
}
通过这种方法,你可以添加尽可能多的自定义的属性,你需要,它真的借给你的具有很大的灵活性,使您能够占到场景众多,当你需要设置各种要素的复杂的权限,你可能会遇到的问题。
禁用包含您的控制也将关闭面板内的控制面板。 小组成员的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?