views:

381

answers:

2

I'd like the child windows in my application to inherit WPF dependency properties from their parent window.

If I set TextOptions.TextRenderingMode="ClearType" on my main window (I'm using WPF 4), that value will apply to all child controls of the window. How can I make those values also apply to all child windows? (Window instances with Owner set to my main window)

I want to be able to simply change the rendering mode on the main window, and the change should apply to the whole application.

A: 

You can use a style resource to give the same property to multiple windows.

antonm
+1  A: 

If you want to set it once and leave it, just add a style to your App.xaml inside your <ResourceDictionary> tag:

<ResourceDictionary>
  ...
  <Style TargetType="{x:Type Window}">
    <Setter Property="TextOptions.RenderingMode" Value="ClearType">
  </Style>
  ...
</ResourceDictionary>

If you actually want to be able to vary it over time, you can bind to the main window:

<ResourceDictionary>
  ...
  <Style TargetType="{x:Type Window}">
    <Setter Property="TextOptions.RenderingMode" Value="{Binding MainWindow.(TextOptions.RenderingMode), Source="{x:Static Application.Current}">
  </Style>
  ...
</ResourceDictionary>

and make sure you set it in the main window explicitly to avoid a self-reference:

<Window TextOptions.RenderingMode="ClearType" ...>

Now any dynamic changes to the TextOptions.RenderingMode of the main window will also affect all other windows. But a simple fixed style is best for most purposes.

There are other solutions for binding it dynamically if you don't care that it be controlled by the main window's value, for example you could use a {DynamicResource ...} in your style or bind to a property of a static object.

Update

Just adding a style for Window in your App.xaml doesn't work if you are using Window subclasses instead of plain Window objects.

To allow the style you define to be applied to all Window subclasses, add the following OverrideMetadata call to your App's constructor (generally in App.xaml.cs) after the InitializeComponent():

public App()
{
  InitializeComponent();
  FrameworkElement.StyleProperty.OverrideMetadata(typeof(Window), new FrameworkPropertyMetadata
  {
    DefaultValue = FindResource(typeof(Window))
  });
}
Ray Burns
Unfortunately a single style doesn't seem to work - it applies only to the type "Window", but my windows are using classes derived from Window.If I specify the x:Type for the derived class, the style works fine - but then it's just as much work as manually setting up bindings for each window class and each property I want to inherit.
Daniel
Sorry, I forgot a small piece of the solution: To make this work you must do a StyleProperty metadata override for Window or use theming. I'll update my answer.
Ray Burns