I am attempting to make a ResourceDictionary of some standardised colour schemes etc to add to a dll class library for use in future applications. I am new to XAML and seem to have made an error when it comes to creating or using the content setter part of the dictionary. I cannot set and use the colour of the text in the dictionary. Here is what I have so far; As you can see, the Foreground of the TextBlock in the Content is set to White.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:My_Class_Library.WPF_Resources">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../WPF Resources/Buttons.xaml"/>
<ResourceDictionary Source="../WPF Resources/Brushes.xaml"/>
<ResourceDictionary Source="../WPF Resources/Sliders.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style x:Key="myButton" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button" >
<Grid>
<Rectangle Name="ClickFill" Fill="ForestGreen" RadiusX="5" RadiusY="5"/>
<ContentPresenter RecognizesAccessKey="True" Content="{TemplateBinding Content}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Content">
<Setter.Value>
<Grid>
<TextBlock Background="{x:Null}" Foreground="White"></TextBlock>
</Grid>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
and here's the reference to the dictionary:
<Grid x:Class="My_Class_Library.Update_Information"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:My_Class_Library"
HorizontalAlignment="Center" VerticalAlignment="Center">
<Grid.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../WPF Resources/Buttons.xaml"/>
<ResourceDictionary Source="../WPF Resources/Brushes.xaml"/>
<ResourceDictionary Source="../WPF Resources/Sliders.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Grid.Resources>
<Button Name="Click"
Width="100" Height="30"
Style="{StaticResource myButton}"
Click="Click_Click">
_click
</Button>
</Grid>
however, what I see is this:
, which as you can see has black (presumably default) text instead of the specified white. What am I doing wrong, that causes the content not to be set?
I know everybody hates questions like "look at this, what's wrong with it?" but I am at my wit's end trying to find a solution - I am following loads of training videos and so on and the above is my best effort... Nearly everything else I try breaks the whole thing! Any pointers very appreciated!
You've kind of got the right idea but you'll want to get used to setting properties from the style template as setter directly. I'd also suggest you start with a default style template of a control and edit it to your needs since like for instance in this case you're going to lose all of the additional Visual states for things like MouseOver etc.
However for the sake of your immediate question, you're going to ditch your Content property all together from the template (that's your ContentPresenter job) and instead just do this (in pseudo);
<Style x:Key="myButton" TargetType="Button">
<Setter Property="Foreground" Value="White"/>
<!-- Rest of it goes here -->
</Style>
...and voila. Hope this helps, cheers!
Related
I created and added the following ResourceDictionary within my App.Resources
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:GanttTesting.Views"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<sys:Double x:Key="CommandCenterExpandedTagRatio">1</sys:Double>
<sys:Double x:Key="CommandCenterCollapsedTagRatio">0</sys:Double>
<sys:String x:Key="CommandCenterCollapsedTagRatioAsString">0.1</sys:String>
<sys:Double x:Key="CommandCenterExpandedWidth">330</sys:Double>
<Style x:Key="CommandCenterStyle" TargetType="{x:Type local:CommandCenter}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid Background="Red" Width="100" Height="100"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
However, when using the "Create new Binding" window in Visual Studio and selecting "Static Resource", while "CommandCenterExpandedTagRatio" and the other String and Double values are displayed properly, "CommandCenterStyle" doesn't appear. Typing it manually doesn't work either.
Did I do something wrong here? Thanks a lot for your help!
Note reading Styles and templates (WPF .NET) and How to create a style for a control (WPF .NET).
<Style x:Key="CommandCenterStyle" TargetType="{x:Type local:CommandCenter}"> in your styles.
This applies the style to the CommandCenter, it doesn't apply to the button control.
This tutorial can teach you how to create a style.
I'm making a DLL for me, to ease my job, because there are classes that I use in every project, so why should i duplicate them, when I can use one DLL to finish the job,
I also wanted to add some controls to it, buttons, so its like this:
I have created a button, and it works well, but I want to add a custom style to it, to disable the background highlighting when you are mouse over, now i have used this style before and works well, but in previous times, I would add the style to the app.xaml resources and then set the style to the button like:
Style="{StaticResource DisableBackgroundHighlight}"
but since the DLL does not have app.xaml, what should I do, how to add style to the control inside the DLL?
All I've found on google was, to reference the resources from the DLL to the app.xaml of the WPF app, but thats not what I want,
I tried this:
<Button x:Class="SRX.Windows.Controls.SRXButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:SRX.Windows.Controls"
mc:Ignorable="d"
d:DesignHeight="35" d:DesignWidth="100" Content="OK" Background="White" BorderBrush="Blue" Foreground="Blue" MouseEnter="Button_MouseEnter" MouseLeave="Button_MouseLeave" Style="{StaticResource DisableBackgroundHighlight}">
<Button.Resources>
<Style x:Key="DisableBackgroundHighlight" TargetType="Button">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="border" BorderThickness="0" BorderBrush="Black" Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" Value="0.8" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Button.Resources>
but it doesnt work, it shows "The resource "DisableBackgroundHighlight" could not be resolved." altough it compiles but crashes on startup.
If I missed something in the problem explanation please ask me to resolve, thanks in advance.
Simply add a xaml file to your project. Let's call it Generic.xaml which is where usually the templates for your custom coltrols will be located .
This file will have the following format:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Your.Domain.Generic">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="whatever else you defined in another xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style TargetType="TextBox" ....
</ResourceDictionary>
on the other assemblies, you import your "style" assembly just like anything else:
xmlns:style="clr-namespace:Your.Domain.Shared"
Supposing of course that you style assembly is named Your.Domain.Shared
I have a ResourceDictionary that contains Style definitions for controls used within my application.
All of the styles are applied properly to the controls in the window...but the style in the ResourceDictionary for the window itself is not being applied.
This is the XAML in my ResourceDictionary that contains the style that I want to apply to my window:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:primatives="clr-namespace:System.Windows.Controls.Primitives;assembly=PresentationFramework"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="{x:Type Window}">
<Setter Property="Background" Value="#FF121212"></Setter>
<Setter Property="Height" Value="768"></Setter>
<Setter Property="Width" Value="1024"></Setter>
</Style>
<!-- .... -->
</ResourceDictionary>
This is the XAML for the window that I am working with (trying to get this style to apply):
<Window x:Class="TryingStyles"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TryingStyles">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources/StylesDictionary.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<StackPanel>
<StackPanel Orientation="Horizontal">
<Label Content="Label" Height="28" HorizontalAlignment="Left" Margin="12,12,0,0" Name="Label1" VerticalAlignment="Top" />
<TextBox Height="23" HorizontalAlignment="Left" Margin="56,14,0,0" Name="TextBox1" VerticalAlignment="Top" Width="120" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TabControl Height="206" HorizontalAlignment="Left" Margin="12,43,0,0" Name="TabControl1" VerticalAlignment="Top" Width="250">
<TabItem Header="TabItem1" Name="TabItem1">
<Grid></Grid>
</TabItem>
</TabControl>
<GroupBox Header="GroupBox1" Margin="268,43,12,12" Width="396"></GroupBox>
</StackPanel>
</StackPanel>
</Window>
It appears that the style for the window is applied when I view the window in the IDE's "Design view" but when I run the application the style is not applied.
Does anyone know what I'm doing wrong?
It appears that there is no proper solution to your problem. TargetType in Styles doesn't manage derived types.
Here are two alternatives :
You can put a key in your style and apply the style to all your Windows.
<!-- Resource file -->
<ResourceDictionary ...>
<Style TargetType="{x:Type Window}" x:Key="WindowDefaultStyle">
<!-- .... -->
</Style>
</ResourceDictionary>
<!-- Window file -->
<Window Style="{DynamicResource ResourceKey=WindowDefaultStyle}">
Or you can use the BasedOn property of the Style.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:my="clr-namespace:WpfApplication1">
<Style TargetType="{x:Type Window}" x:Key="BaseStyle">
<Setter Property="Background" Value="#FF121212"></Setter>
<Setter Property="Height" Value="768"></Setter>
<Setter Property="Width" Value="1024"></Setter>
</Style>
<!-- Inherit from the BaseStyle and define for the MainWindow class -->
<Style TargetType="{x:Type my:MainWindow}" BasedOn="{StaticResource ResourceKey=BaseStyle}" />
</ResourceDictionary>
It's very strange that it works with the designer but not when the application runs.
The problem seems to be the TargetType of your Style. Wpf seems not be able to match the Window class with your derivated class TryingStyles.
Change your TargetType and it will work :
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:primatives="clr-namespace:System.Windows.Controls.Primitives;assembly=PresentationFramework"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:my="clr-namespace:WpfApplication1">
<Style TargetType="{x:Type my:TryingStyles}">
<Setter Property="Background" Value="#FF121212"></Setter>
<Setter Property="Height" Value="768"></Setter>
<Setter Property="Width" Value="1024"></Setter>
</Style>
<!-- .... -->
</ResourceDictionary>
I'm quite late to the party here, but I found a solution to have Style TargetType="{x:Type Window}" apply to every window application-wide, as one would expect. For the record, the reason this doesn't work is because each window you create is not a Window but a new type that derives from window (e.g. "MainWindow"), and Style's TargetType doesn't apply to derived classes. Anyway:
First, ensure your App.xaml has a Startup property defined; so inside the <Application> tag you'd add Startup="Application_Startup" or whatever you want to call the startup method.
Then, inside App.xaml.cs add:
private void Application_Startup(object sender, StartupEventArgs e)
{
FrameworkElement.StyleProperty.OverrideMetadata(typeof(Window), new FrameworkPropertyMetadata
{
DefaultValue = Application.Current.FindResource(typeof(Window))
});
}
where the method name matches whatever you listed as the Startup property in App.xaml. And of course, if you already have an existing startup method being run, just add the code contained within to that.
This basically just fixes it so that keyless Styles targeting "Window" will apply their changes to every window in your application, as you probably expected would occur without this code snippet. (That is of course assuming your style is already scoped application-wide, for example by containing it within a ResourceDictionary that is merged into App.xaml.)
I have an application with a large number of styles that are currently duplicated in the .xaml for each window of the application. I would like to be able to reference one file called UiStyles.xaml that contains all of the styles for the application.
After reading a ton of answered questions on here and Google I've tried this:
ButtonStyle.xaml:
<Style TargetType="{x:Type Button}" x:Key="ButtonStyle">
<Setter Property="Background" Value="Red"/>
<Setter Property="FontSize" Value="48"/>
</Style>
</ResourceDictionary>
UiStyles.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ButtonStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style TargetType="Control" /> <!-- Added this based on other user's suggestions to account for .net 4 bug -->
</ResourceDictionary>
MainWindow.xaml:
<Window x:Class="TestingGround.UI.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<ResourceDictionary Source="Resources/UIStyles.xaml"/>
</Window.Resources>
<Grid>
<Button Click="ButtonBase_OnClick" Content="Test Text"/>
</Grid>
</Window>
But my button style is not being applied! What am I doing wrong?
Note when you apply a key to a style, you have to explicitly apply it to the control so
<Button Click="ButtonBase_OnClick"
Content="Test Text"
Style={StaticResource ButtonStyle} />
However if you want all buttons to default to the style remove the x:key="ButtonStyle".
<Style TargetType="...">
You have created your button style with an x:Key, but are not referencing that in your button instance.
You need to set the "Style" property of the button like so:
<Button Click="ButtonBase_OnClick" Style="{StaticResource ButtonStyle}" Content="Test Text"/>
I know that Silverlight 5 introduces the data binding in styles. I want to bind the source of image which is present in content template in the style of a button.
I am using the below code where I am trying to set the image source property in style.
// Style
<UserControl x:Class="MGPIControls_Simple.ButtonControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows"
Height="40" Width="40"
mc:Ignorable="d" x:Name="ButtonControlSample">
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.Resources>
<Style x:Key="ImageButtonStyle" TargetType="Button">
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<!-- binding in style -->
<Image Source="{Binding ImageSource}"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Stretch="Fill"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</Grid.Resources>
<Button x:Name="ButtonBase" Style="{StaticResource ImageButtonStyle}"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
</Grid>
Where ImageSource is the dependency property I have created. If I dont bind the image source property and keep it static to some image url the things are working fine but binding is not working. Please let me know where I am wrong in above approach.
You have to use binding like
<TextBlock Text="{Binding Path=DataContext.BusyText, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}"
Well, how to put this... what you try to do is not the new Silverlight 5 feature Binding in Styles. This kind of binding is always possible, even with older Silverlight versions.
You have a DataTemplate and that means any binding you declare is evaluated when actual UI elements are instantiated from the template. And your binding Source="{Binding ImageSource}" is evaluated against your Button's DataContext.
If there is no public property ImageSource then your Button won't show any image.