I've been tinkering around with WPF MDI, which sets the control template for MDI Child objects. So when you add an MdiChild object and set its Content to a UserControl it looks good, but if you inherit from MdiChild then it doesn't work.
The template code looks something like this:
<Style TargetType="{x:Type local:MdiChild}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:MdiChild}">
<!-- ... -->
I'd like this template to apply not just to MdiChild, but also to anything that derives from it. How can I go about this? The only way I can think of is to create a style targeting each derived class that is based on the MdiChild style, but that's not very desirable.
You have to declare style for each derived type but with WPF you have power to inherit from base style using BasedOn.
<Style TargetType="{x:Type local:DerivedMdiChild}"
BasedOn="{StaticResource {x:Type local:MdiChild}}">
......
</Style>
This way all setters, triggers etc. will be inherited and you don't have to redefine them again for each derived style. Moreover, it gives you power to override setter of base style in case you want some different behaviour in derived version.
Related
I have a back button which is copied almost to all the Controls in my application.
I have set the styles and properties of the button on each individual control (usercontrol)
Now I want to change the text property of the button of all the control (usercontrol).
I don't want to go and change the property of each control.
Please help me setting a global property which sets the property in one place.
Since the style is common to all pages. Create the style without a key/name, just the target type would do.
<Style TargetType="{x:Type Button}">
Then do either of the following -
Add it to the App.XAML for visibility throughout the app
Better approach would be to define a resource dictionary file and import it, wherever you need it.
<Style TargetType="{x:Type Button}">
<Setter Property="Text" Value="{Binding text}" />
<Setter Property="...." Value="{Binding ....}"/>
</Style>
Add this to App.xaml file as you want it to be global style for all your user controls.
I'd like to understand which properties of an xaml Control are applied to the ControlTemplate of that Control. F.e. If I create a Control based on the Window Class like this:
(This is very simplified — It doesn't make sense in the current state I know...)
public class BaseWindow : Window {
public BaseWindow() { }
}
And the Template:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:shell="clr-namespace:Microsoft.Windows.Shell;assembly=Microsoft.Windows.Shell"
xmlns:local="clr-namespace:Arctic">
<Style TargetType="{x:Type local:BaseWindow}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:BaseWindow}">
<Grid Background="Transparent">
<Border Background="{TemplateBinding Background}"/>
<ContentPresenter/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
Now, when I specify a BaseWindow Control in my app the Margin Property is applied to the BaseWindow without specifying a TemplateBinding. The Background isn't, I have to declare the TemplateBinding in the Template in order to achieve that. Can you explain to me why some properties are applied to the ControlTemplate by default and others are not?
My guess is, that the Window.xaml (Default Window Template of WPF) binds to some properties like the Margin but ignores some like Background. If that is true, then I do not understand why I can set the Background in a Window Control and it is applied to it. Seems like the Window binds to some properties and stops doing that when you derive from it…
This is probably completely wrong — I just wanted to explain my thoughts.
Window class inherit FrameworkElement and all its properties including FrameworkElement.Margin. Same goes for Control.Background. Your question is why you have to do something to have Control.Background working.
Answer is simple:
Margin is used in layouting, its functionality is implemented/provided by FrameworkElement and it happens always, invisible for you and disregarding of ControlTemplate (because all framework elements participate in layouting and use margin).
Background, in turn, is provided to be use by visuals. It's up to you how to use it, because only you know how control will looks like. Control doesn't know what to do with that property.
So, you have to use TemplateBinding to bind Background to some color in your ControlTemplate, but Margin works without need to do anything in control template.
I use Telerik as a WPF library. We can apply a theme on Telerik controls using application Theme (i.e. theme manager). For Microsoft controls we can set a property to make the theme apply.
The problem is : I don't want to write this line :
<Style TargetType="{x:Type CheckBox}">
<Setter Property="telerik:StyleManager.Theme" Value="{Binding Source={StaticResource Settings}, Path=Default.Theme}" />
</Style>
for every type: CheckBox, TextBlock, TextBox etc.. for maintenance purpose.
If I target <Style TargetType="{x:Type Control}"> inheritance doesn't work well.
Base class of CheckBox is Control but when I set property on every control it doesn't set property on every child of control too. Any idea how i can do this?
I have a custom class that is derived from userControl, it describes what features a "service window" should have. It should also describe how a instance of this "service window" should look.
I have a style called serviceStyle. now whenever i create a new instance of the service window, i have to manually set the style in the XAML of the instance, when possible i want to avoid having to do this by basically forcing the style to all childs of service window to serviceStyle. Then i want to be able to do a fade animation on a textBlock in serviceStyle. Now since this is the style of a child of the "Service window" it seems unreachable...
In the meantime i found a way to Set the Style as a default style for all the service windows, this can be done by adding this line in the constructor:
DefaultStyleKeyProperty.OverrideMetadata(typeof(NetcarityService), new FrameworkPropertyMetadata(typeof(NetcarityService)));
Now i need to be able to get from the source to the element textBlock in the xaml of the ServiceWindowStyle....
Thanks in advance.
You don't need to do that in order to make a default style, you just define your style without a key. For example, this style applies to all button in an app (if the style is defined in app.xaml)
<Style TargetType="{x:Type Button}">
<Style.Setters>
<Setter Property="Margin" Value="6"></Setter>
<Setter Property="Padding" Value="6,3,6,3"></Setter>
</Style.Setters>
</Style>
With regards the children I would think you just need to write some code to detect when a child is added and set the default style for the child. I think you can just override OnVisualChildrenChanged.
PS. Setting DefaultStyleKeyProperty should be done in the static constructor
I am deriving from Combobox to add some additional functionality, such as a checkbox.
The issue is, even with a simple implementation the Items.Add method does not work.
For example, here is the XAML:
<Style TargetType="{x:Type local:CustomControl1}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:CustomControl1}">
<ComboBox>
</ComboBox>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The ComboBox is visible, but no information is added when I call the Items.Add method. What do I need to implement from the ComboBox class to achieve this? Do I need to do something with the popup? Add a Textblock?
That doesn't look to me like you're deriving from ComboBox... It looks to me like you're putting a ComboBox inside the ControlTemplate of your custom control.
If you are also deriving your custom control from ComboBox and calling Items.Add on your custom control, then you've basically got two lists of data (one for your custom control and one for the combobox in your controltemplate) and they are not linked in any way.
I'd suggest popping open Expression Blend and taking a look at the control template for a default ComboBox. If you want to derive from ComboBox you can then modify that controltemplate to suit your needs.