Something that's worked well for us is to define a view model that represents the permission structure of your application (YourPermissionsViewModel in my example below).
Then you could create a custom panel control that extends any panel of your choice (StackPanel in this example). That way you can add in the IsReadOnly property bindings and persist them to the panel's children.
Here's what the panel in XAML could look like:
<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>
And here is the StackPanel extension control containing all of StackPanel's features as well as attaching a custom IsReadOnly dependency property that updates the corresponding property value on any child controls who possess that property:
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);
}
}
}
With this approach you could add as many customized properties you need, it really lends you a great deal of flexibility and enables you to account for a multitude of scenarios you might encounter when you have to set your complex permissions on various elements.