Setting WPF style on Window - wpf

I wrote an XAML code in wpf, i defined a style in window.resourse like this
<Window x:Class="WpfApp1.Test"
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:self="clr-namespace:WpfApp1"
xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:local ="clr-namespace:WpfApp1"
mc:Ignorable="d"
Height="400 " Width="450" >
<Window.Resources>
<Style TargetType="{x:Type Window}">
<Setter Property="Title" Value="Hello my friens!"/>
</Style>
</Window.Resources>
<Grid>
</Grid>
in here, Test is my window class name. when i run that everything is ok but when i changed above to this
<Window.Resources>
<Style TargetType="{x:Type Window}">
<Setter Property="Title" Value="Hello my friends!"/>
</Style>
</Window.Resources>
in design window, title showed as Value="Hello my friends!" but when i run the application, title become empty.
what this happens?
what is different btw TargetType="{x:Type Window}" and TargetType="{x:Type local:Test}" ?
did not every of them refer to window type ?

By just specifying the targettype in a style, the style automatically applies to all objects of the type you defined it for. However, that does not work for base classes.
In your example, TargetType="{x:Type Window}" will automatically apply the title "Hello my friends!" to all windows. However, the type of your window is not Window, but WpfApp1.Test. Window is just the base class that is used. Thats why the style doesn't apply to the window automatically.
If you use TargetType="{x:Type local:Test}" instead, it will apply automatically to all objects that have the type WpfApp1.Test, which is true for your window. The automatic applying of styles only works for the specific type, not the base class.
You can also specify a key attribute, and then tell your window that it should use this style. In this case, you can also use x:Type Window, because then the style is being applied explicitly.
e.g.:
<Window x:Class="WpfApp1.Test"
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:self="clr-namespace:WpfApp1"
xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:local ="clr-namespace:WpfApp1"
mc:Ignorable="d"
Height="400 " Width="450" Style="{DynamicResource MyStyle}">
<Window.Resources>
<Style TargetType="{x:Type Window}" x:Key="MyStyle">
<Setter Property="Title" Value="Hello my friends!"/>
</Style>
</Window.Resources>

Related

how to disable cut, copy paste and right click across all WPF forms

We are building a WPF kiosk application.
We need to disable CUT COPY PASTE and RIGHT-CLICKs
Please how can this be done?
This SO post does not give a centralized solution for all forms:
How to suppress Cut, Copy and Paste Operations in TextBox in WPF?
You need to add a Style in your App.xaml in which you define:
<Style TargetType="TextBox">
<!-- OR -->
<Style TargetType="{x:Type TextBox}">
<Setter Property="ContextMenu" Value="{x:Null}"/>
</Style>
But this will only work for the Items that are NOT in a DataTemplate.
UPDATE:
App.xaml:
<Application x:Class="TestApp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TestApp"
StartupUri="MainWindow.xaml">
<Application.Resources>
<Style TargetType="{x:Type TextBox}">
<Setter Property="ContextMenu" Value="{x:Null}"/>
</Style>
</Application.Resources>
And here is the MainWindow.xaml:
<Window x:Class="TestApp.MainWindow"
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"
xml:lang="en-GB"
xmlns:local="clr-namespace:TestApp"
xmlns:converter="clr-namespace:TestApp.Converters"
mc:Ignorable="d"
Height="478.889" Width="903.889">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.3*"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackPanel>
<TextBox Name="txtBx" MinHeight="150"
VerticalAlignment="Top" AutoWordSelection="True"
MaxLines="10"
TextWrapping="WrapWithOverflow"
SelectionChanged="txtBx_TextHighlighted"
ToolTip="{x:Null}"
Margin="10"/>
</StackPanel>
</Grid>
If you Right Click on the TextBox you will not have any ContextMenu available to you.
UPDATE 2:
Continuing from our chat, the TextBox was referencing other styles which were overriding whatever we set in the App.xaml. As the external styles were loaded after the App.xaml.

Apply a style to all textbox in my WPF application

I am having an issue while I want to apply a style (font size) to all my textbox, where ever they are.
I, of course found those links :
Apply an application-level style to all textboxes
How to target all controls (WPF Styles)
But this doesn't work for me.
The first one is still better because you don't need to use a key, and going to all your textbox.
I already have, in my app.xml, style applying to all controls (applying a color), so I tried something like this (even if this won't really be enough for me, since those styles are not everywhere) :
<Style x:Key="Type1Data" TargetType="{x:Type Control}">
<Setter Property="Background" Value="#FEE9E6"/>
<Style.Resources>
<Style TargetType="{x:Type TextBox}">
<Setter Property="FontSize" Value="50" />
</Style>
</Style.Resources>
</Style>
And as I said, I tried this too, but won't work.
<Style TargetType="{x:Type TextBox}">
<Setter Property="FontSize" Value="50" />
</Style>
Any idea what is my probleme and how I can achieve what I want to?
All the hings I can find make me come back to the same code, and didn't found one that works.
edit : here is my current app.xaml
<Application x:Class="myApp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:myApp"
StartupUri="MainWindow.xaml">
<Application.Resources>
<Style TargetType="TextBox"><!-- tried adding those 3 lines too-->
<Setter Property="FontSize" Value="50"/>
</Style>
<Style x:Key="Type1Data" TargetType="{x:Type Control}">
<Setter Property="Background" Value="Blue"/>
</Style>
<Style x:Key="Type2Data" TargetType="{x:Type Control}">
<Setter Property="Background" Value="White"/>
</Style>
<Style x:Key="Type3Data" TargetType="{x:Type Control}">
<Setter Property="Background" Value="Green"/>
</Style>
</Application.Resources>
</Application>
As I said, the current styles does not cover the whole app (I add the key that is needed, or nothing)
edit : and if I add directly (as a second setter) font size to the Type 1,2 or 3, the font size apply. So it seems, there is no oter styles that are applying besides the 3 in app.xml.
<Setter Property="FontSize" Value="50" />
Sample of code who should get a different textbox size(one with already a style, one without), they are in grid:
<com:ViewControl x:Class="myApp.View.ViewControl"
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:syncfusion="http://schemas.syncfusion.com/wpf"
xmlns:input="http://schemas.syncfusion.com/wpf"
xmlns:local="clr-namespace:myApp.View"
xmlns:com="clr-namespace:RAPINF.PLL.Common;assembly=myApp.Common"
xmlns:entities="clr-namespace:myApp.Entities;assembly=myApp.Entities"
mc:Ignorable="d"
d:DesignHeight="500" d:DesignWidth="700">
<TextBox Style="{StaticResource Type1Data}" Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2" Margin="2" Text="{Binding Data.Name}" VerticalAlignment="Center" />
<TextBox Grid.Row="0" Grid.Column="1" Margin="2" Text="{Binding Data.Name}" VerticalAlignment="Center" Grid.ColumnSpan="3" />
edit : adding the code of the popup I use sometimes and works
<sf:RibbonWindow x:Class="namespace:myApp.Common.DetailViewWindow"
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:sf="http://schemas.syncfusion.com/wpf"
xmlns:self="clr-namespace:myApp.Common"
mc:Ignorable="d"
d:Height="300" d:Width="400"
WindowStartupLocation="CenterOwner"
>
</sf:RibbonWindow>
How my usercontrol is added to the dock :
public void AddView(UserControl View, string sTitle, DockState docState)
{
int Width = 800;
int Height = 400;
DockingManager.SetHeader(View, sTitle);
DocumentContainer.SetMDIBounds(View, new Rect(30, 30, Width, Height));
DockingManager.SetState(View, docState);
DockingManager.SetShowCloseMenuItem(View, true);
DockingManager.SetDesiredWidthInDockedMode(View, Width);
DockManager.Children.Add(View);
ActivateView(View);
}
If I use the dock I do this before :
ApplicationContext.Current.AddView(View, DockState.Document);
ANd with a popup, almost the same :
DetailViewWindow dlg = new DetailViewWindow(View);
dlg.ShowDialog();
As, those two code are used with the same View (yes, exactly the same), then I guess the problem comes from the fact of adding the view in the dock, and not in a popup window.
Does the dock manager forces me to use a key?
Thank you for your help.
I can't reproduce your problem. I can just show you a working example. Maybe it's helping you finding your problem.
App.xaml
<Application x:Class="WpfApplication2.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication2"
StartupUri="MainWindow.xaml">
<Application.Resources>
<Style TargetType="{x:Type TextBox}">
<Setter Property="FontSize"
Value="50" />
</Style>
</Application.Resources>
</Application>
MainWindow.xaml
<Window x:Class="WpfApplication2.MainWindow"
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:WpfApplication2"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
mc:Ignorable="d"
Title="MainWindow"
Name="MyWindow"
SizeToContent="WidthAndHeight">
<TextBox Width="150"/>
</Window>
Output
I too had no problem with the styling. But I typically break my stuff into separate dictionaries for different controls and derive from some of my own classes. I also define a style and assign a "x:Key" name to it. This is like saying I have a class with this key name and I want it to look like this. Then, once I get it working, I take the final class and say use your style based on the key defined... Having said that, Here is a stripped basic of the App.xaml
<Application.Resources>
<Style TargetType="TextBox" x:Key="STextBox">
<Setter Property="FontSize" Value="50"/>
<Setter Property="FontFamily" Value="WingDings" />
</Style>
<Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource STextBox}" />
</Application.Resources>
I can define all sorts of things about my base-style "STextBox" (via the x:Key). But after, I set the style with a target BASED ON the style via x:Key. The critical thing I think you were missing is the target must be of {x:Type TextBox}.
If you look at the xmlns headers at the top such as
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
the "x=" is the alias of the library it is getting control types. By you generically declaring the
TargetType="TextBox"
You are not specifically associating to the CLASS TYPE.
Then in my main window (and anywhere else in the app), I have this in my main grid
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="80" />
<RowDefinition Height="80" />
<RowDefinition Height="80" />
</Grid.RowDefinitions>
<TextBox Grid.Row="0" Text="Testing" />
<TextBox Grid.Row="1" Text="Another Line" />
<TextBox Grid.Row="2" Text="Last" />
</Grid>
and they all work properly. You can also change default colors, size, font family, margins, etc to the base style and all will change without explicit reference to every control.

Override Specific Style Properties using Resource Dictionary

I am trying to override the styles of Material Design for Xaml ToolKit as per my requirements, the following is the xaml in app.xaml which i came up with after reading about overriding on the github page of the library, but it seems to be not working and i am not getting why, as i have not much experience working in WPF applications, here is the code i tried:
<Color x:Key="DarkBlueColor">#00479D</Color>
<FontFamily x:Key="MicrosoftYaHei">Microsoft YaHei</FontFamily>
<SolidColorBrush x:Key="WindowBrush" Color="#00479D"/>
<Style x:Key="WindowStyle"
x:Name="WindowStyle"
BasedOn="{StaticResource MaterialDesignPaper}"
TargetType="{x:Type Window}">
<Setter Property="Background" Value="{DynamicResource WindowBrush}"></Setter>
</Style>
For the time being to get familiar i am only trying to change the background of the window, here is the code from MainWindow.xaml:
<Window x:Class="WPFApplication.MainWindow"
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:XCMG.CarMan2"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525"
Style="{StaticResource WindowStyle}"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes">
<Grid>
</Grid>
</Window>
When i run the application after adding the above code, it throws an exception saying:
Unable to cast object of type 'System.Windows.Media.SolidColorBrush' to type 'System.Windows.Style'.
"MaterialDesignPaper" is a SolidColorBrush and you can't base a Window style on a Brush.
Remove the BasedOn attribute and the x:Name from your Style:
<Style x:Key="WindowStyle"
TargetType="{x:Type Window}">
<Setter Property="Background" Value="{DynamicResource WindowBrush}"></Setter>
</Style>
but i want override MaterialDesignBrush BackGround
Define a new Brush resource with the same key then:
<SolidColorBrush x:Key="MaterialDesignPaper" Color="#00479D"/>

WPF/XAML: Set a style with a different TargetType?

I have an external style resource in a resource dictionary I'm referencing with x:Key. It has an x:TargetType specifying a target (TextBlock). Is it possible to apply this to a control containing a TextBlock and have all TextBlock elements within that control have the style applied?
Thanks,
Robert
The easiest way to do that would be to define a Style within the Control that is based on your external style resource, but don't specify an x:Key, just the TargetType.
<Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource SomeOtherStyle}">
Without a key, it'll apply itself to all TextBlocks within the control.
To expand a bit on other comments. When you use the syntax as Brandon showed:
<Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource SomeOtherStyle}">
The BasedOn="" is basically a kind of "inheritance" of style. This style will have as its base set of setters the ones from the style it is based on. This gives you the ability to augment the style with the options that apply only in this case or, as your case requires, to redefine the scope of the style.
You have the style in your dictionary file as a keyed style, only able to be applied explicitly. By "re-defining" your style as Brandon showed you now can re-define the scope by leaving out the key, thus making it apply to all elements of the target type in the scope of that style. So if all your TextBlocks were in a Grid you could have something like this:
<Grid.Resources>
<Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource MyBaseStyle}">
</Style>
</Grid.Resources>
No, but you can automatically apply a style to all elements of a certain type, like this:
<!-- Applies to all buttons in scope of this style -->
<Style x:Key="{x:Type Button}" TargetType="{x:Type Button}">
...
</Style>
I think this is what you are looking for:
Your custom user control "test":
<UserControl x:Class="WpfApplication4.test"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300">
<Grid>
<TextBlock>test</TextBlock>
</Grid>
</UserControl>
Your Styles document "Res/Styles.xaml"
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="{x:Type TextBlock}">
<Style.Setters>
<Setter Property="Foreground" Value="Blue" />
</Style.Setters>
</Style>
Your main window or parent:
<Window x:Class="WpfApplication4.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:uc="clr-namespace:WpfApplication4"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Res/Styles.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
<uc:test></uc:test>
</Grid>
The textblock in the custom control "test" now displays with a blue foreground.

WPF custom control style problem

I have a custom control (from MS Toolkit - DatePicker). I've made my own style like this:
<Style TargetType="{x:Type local:DatePicker}">
But this style does not apply automatically. I have to add Key:
<Style x:Key="DatePickerStyle" TargetType="{x:Type local:DatePicker}">
and reference it in each custom control like
<toolkit:DatePicker Style="{StaticResource DatePickerStyle}"
...
to get it working. Does anyone know why?
have you tried changing the TargetType to:
TargetType="{x:Type toolkit:DatePicker}">
You are referencing local in one place and toolkit in another.
update:
I've tried it in a small app. This is the xaml as it should work:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="WpfApplication3.Window1"
x:Name="Window"
Title="Window1"
Width="640" Height="480"
xmlns:Toolkit="http://schemas.microsoft.com/wpf/2008/toolkit">
<Window.Resources>
<Style TargetType="{x:Type Toolkit:DatePicker}">
<Setter Property="Background" Value="#FFFF0000"/>
</Style>
</Window.Resources>
<Grid x:Name="LayoutRoot">
<Toolkit:DatePicker HorizontalAlignment="Left"
Margin="61,143,0,116" Width="232" />
</Grid>
</Window>
This example should create a datepicker with a red background.

Resources