WPF custom control style problem - wpf

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.

Related

Custom Window Style not showing in design view

I am attempting to customize the window style in a WPF application in VS2019 (.NET Core 3.1). I'm following along with a video, currently adding the style directly to the MainWindow.xaml. None of my style shows up in the XAML design view (in the video it does), however, the style shows correctly at runtime.
All other styles show up fine. I dug around looking for perhaps a window style I had set somewhere else but I'm not finding anything. At first, I was having an error on the inner <WindowChrome.../> saying "object of type 'Microsoft.VisualStudio.XSurface.Wpf.Window' cannot be converted to type 'System.Windows.Window'" but that issue appears to have resolved itself. I'm not sure if that is related or a clue.
Any idea what is going on and how to fix it? Or perhaps a hack to force a design-time style to take so I can see what I'm doing?
Code:
<Window x:Class="FirmwareUpdater.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:FirmwareUpdater"
xmlns:vm="clr-namespace:FirmwareUpdater.ViewModels"
mc:Ignorable="d"
WindowStyle="None"
WindowStartupLocation="CenterScreen"
x:Name="AppWindow"
Title="Firmware Updater"
Height="600" Width="800">
<Window.Resources>
<Style TargetType="{x:Type local:MainWindow}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<Border Background="Gray" Padding="{Binding OuterMarginSize, FallbackValue=10}">
<Grid Background="Red">
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<WindowChrome.WindowChrome>
<WindowChrome
CaptionHeight="{Binding TitleHeight}"
ResizeBorderThickness="0"
GlassFrameThickness="0"
CornerRadius="0"/>
</WindowChrome.WindowChrome>
<Grid>
<!-- Displays pages for navigation-->
<Frame x:Name="mainFrame"
MaxHeight="600" MaxWidth="800" Margin="0,0,0,0"
NavigationUIVisibility="Hidden" />
</Grid>
</Window>
Recently, I was following this tutorial series and got this problem too, no matter which designer I use: NetFramework or NetCore.
For me, the only way to see changes during design-time is to define the ControlTemplate with a key in Window.Resources and set Window's Template as DynamicResource:
<Window ...
Template="{DynamicResource WindowBase}">
<Window.Resources>
<ControlTemplate x:Key="WindowBase" TargetType="{x:Type Window}">
</ControlTemplate>
</Window.Resources>
</Window>
I don't know how much this solution is reliable, but at least I don't have to run my app to see changes.
EDIT
You can also move the ControlTemplate from Window.Resources to some ResourceDictionary and set it as StaticResource for your Window's template.

Setting WPF style on Window

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>

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.

Split TabItem cause style lost

I've a TabControl with this structure:
<TabControl>
<TabControl.Resources>
<Style TargetType="TabItem" BasedOn="{StaticResource MetroTabItem}">
<Setter Property="Controls:ControlsHelper.HeaderFontSize" Value="20" />
</Style>
</TabControl.Resources>
<local:Analysis />
</TabControl>
Now I need to split each TabItem, so I've create something like a UserControl with this structure:
<TabItem 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:Controls="http://metro.mahapps.com/winfx/xaml/controls"
mc:Ignorable="d" Header="Analysis" Style="{StaticResource MetroTabItem}">
<Grid>
</Grid>
the problem's that the TabItem imported with namespace local: doesn't take the style of the TabControl in the Resource.
So for solve this I need to put the style resource in each TabItem, this will cause redundancy code.
How can I take the style of TabControl Resource in the splitted TabItem?
Thanks.
You can create your own style as a static resource in your App.xaml or your Window.xaml like this:
<Application.Resources>
<Style TargetType="TabItem" x:Key="MyTabItemStyle" BasedOn="{StaticResource MetroTabItem}">
<Setter Property="Controls:ControlsHelper.HeaderFontSize" Value="20" />
</Style>
</Application.Resources>
You give your style a name (MyTabItemStyle in this example) which is based on the MetroTabItem style.
Then, instead of using the MetroTabItem style directly in your custom TabItem, you use your own style MyTabItemStyle like this:
<TabItem 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:Controls="http://metro.mahapps.com/winfx/xaml/controls"
mc:Ignorable="d" Header="Analysis" Style="{StaticResource MyTabItemStyle}">
<Grid>
</Grid>
</TabItem>

Resources