对我们来说行之有效的方法是定义一个表示应用程序权限结构的视图模型(在下面的示例中为 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);
}
}
}
使用这种方法,您可以添加所需的任意数量的自定义属性,它确实为您提供了很大的灵活性,并使您能够在必须对各种元素设置复杂权限时考虑可能遇到的多种情况。