Setting styles for subcontrols of usercontrol - wpf

Say I have a user control like this:
<UserControl x:Class="StyleTest.UserControl1"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Button Grid.Row="0">Style please</Button>
<Button Grid.Row="1">Style please</Button>
</Grid>
And I want to set all buttons in this control to background=green.
But I don't want to affect other buttons in my program and I don't want to modify the code of the control.
What I found right now is this:
<Window x:Class="StyleTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:loc="clr-namespace:StyleTest"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style x:Key="UserControlStyles" TargetType="Button">
<Setter Property="Background" Value="green" />
</Style>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Button Grid.Column="0">no Style please</Button>
<loc:UserControl1 Grid.Column="1">
<loc:UserControl1.Resources>
<Style TargetType="Button" BasedOn="{StaticResource UserControlStyles}" />
</loc:UserControl1.Resources>
</loc:UserControl1>
</Grid>
But this would imply that I have to add this code to every instance of the control, and some extra code, if I want to style e.g. foreground color of TextBoxes also.
What I am looking for is something similar to this:
<Style TargetType="Buttons that are childs of UserControl1">
<Setter Property="Background" Value="green" />
</Style>
Is there a way of doing this?
I don't think that a control template would be sufficient, because I don't want to redesign the whole control, I just want to set the color of the buttons.

In App.xaml you could add this style which will be applied to all instances of UserControl1
<Style TargetType="StyleTest:UserControl1" >
<Style.Resources>
<Style TargetType="Button">
<Setter Property="Background" Value="green" />
</Style>
</Style.Resources>
</Style>

If I understand correctly, you just need to modify your UserControl so that you add the style there, instead of in the Window control
<UserControl x:Name=UserControl1 ...>
<UserControl.Resources>
<Style TargetType="Button">
<Setter Property="Background" Value="green" />
</Style>
</UserControl.Resources>
I just saw that you said you don't want to modify the control. You mean that you can't modify the xaml of the UserControl? Why not?

Related

Extend style without setting an x:Key attribute in the base style

I have a file MyButtonStyles.xaml which designs the WPF button. This file uses a style to set some colors and fonts:
<ResourceDictionary xmlns......>
<Style BasedOn="{StaticResource {x:Type Button}} TargetType="{x:Type Button}">
<Setter Property="Foreground" Value="Blue" />
<Setter Property="FontSize" Value="22" />
</Style>
</ResourceDictionary>
This button is used in two xaml files. One shows the button as designed in the above style. This happens automatically because the above style has the according TargetType and it does not have an x:Key attribute.
In the other xaml file I use this button as well but the style from above should be extended by another setter property. Doing this by merging the dictionaries and basing on the original style it works:
<ResourceDictionary>
<ResourceDictionary.MergedDictionary>
<ResourceDictionary Source="MyButtonStyles.xaml" />
<ResourceDictionary.MergedDictionary>
<Style BasedOn="ButtonStylesOrig" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Green" />
</Style>
</ResourceDictionary>
But for this I have to add an x:Key attribute (ButtonStylesOrig) to the base style. This means that in the first xaml which uses the button the base style will not be applied any more.
Is there a possibility to extend a style without losing the global scope of it (e.g. without using x:Key)?
This works:
<Window x:Class="WpfApplication1.Window1"
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"
mc:Ignorable="d"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="MyButtonStyles.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
<Grid.Resources>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Background" Value="Green" />
</Style>
</Grid.Resources>
<Button Content="Button" />
</Grid>
</Window>
The key is not to override the resource in the same resource dictionary that you merge your base style into:
WPF Using multiple Resource Dictionaries from multiple projects
You can't combine multiple default styles of the same type a single resource scope. However, it is possible to build default styles in nested resource scopes.
Suppose you merge MyButtonStyles.xaml into the App.xaml resources. Then you can place your second style with the additional setter into Window.Resources or other deeper nested resources and it will combine the correct implicit styles.
A more localized example:
<Grid>
<Grid.Resources>
<ResourceDictionary Source="MyButtonStyles.xaml"/>
</Grid.Resources>
<Grid>
<Grid.Resources>
<Style BasedOn="{StaticResource {x:Type Button}}" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Green" />
</Style>
</Grid.Resources>
<Button VerticalAlignment="Top" Margin="20">Both styles</Button>
</Grid>
<Button VerticalAlignment="Center" Margin="20">ExampleDictionary style</Button>
</Grid>

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.

Make all windows WindowStartupLocation default to CenterScreen

I had asked this question the other day. Now, I'm trying to apply the same practice to make all my windows, and have CenterScreen as it's default WindowStartupLocation. I've tried typing:
<Style TargetType="Window">
<Setter Property="WindowStartupLocation">
</Setter>
</Style>
However, apparently WindowStartupLocation isn't a supported property for this. Is there a way to accomplish this that I'm missing, or am I going to have to manually change this for all windows?
App.xaml
<Application.Resources>
<ResourceDictionary>
<Style x:Key="WindowStyle" TargetType="Window">
<Setter Property="SizeToContent" Value="WidthAndHeight" />
<Setter Property="ResizeMode" Value="CanMinimize" />
</Style>
<WindowStartupLocation x:Key="WSL">CenterOwner</WindowStartupLocation>
</ResourceDictionary>
</Application.Resources>
Window
<Window x:Class="WpfApplication7.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Width="525" Height="350" WindowStartupLocation="{StaticResource WSL}" Style="{StaticResource WindowStyle}">
<Window.Resources />
<Grid />
</Window>

How to write styles to callouts wpf

I'm using the next namespace (http://schemas.microsoft.com/expression/2010/drawing).
I've two controls for the collout which use the same styles.
i want to write some reusable style for those two controls, but no success...
Any suggestions?
You can reuse styles, whether it's for callouts or any other control, by making them resources and referencing them later. For example:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing"
x:Class="WpfApplication1.MainWindow">
<Window.Resources>
<Style x:Key="MyCalloutStyle" TargetType="ed:Callout">
<Setter Property="Fill" Value="Orange" />
</Style>
</Window.Resources>
<Grid x:Name="LayoutRoot">
<ed:Callout Style="{StaticResource MyCalloutStyle}" />
<ed:Callout Style="{StaticResource MyCalloutStyle}" />
</Grid>
</Window>

Resources