ResourceDict share & set Template - wpf

I will use XAMLReader to load wpf screens.
I have some ControlTemplates on Buttons.xaml file and i am keeping it in a common class library (ClassLibrary1).
Buttons.xaml is like that:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ControlTemplate x:Key="LeftButton" TargetType="{x:Type Button}">
// Some codes
</ControlTemplate>
<ControlTemplate x:Key="RightButton" TargetType="{x:Type Button}">
// Some codes
</ControlTemplate>
</ResourceDictionary>
On main WPF project, this dll is added as reference.
My xaml is like that:
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="800" Height="600">
<Grid>
<Grid.Resources>
<ResourceDictionary x:Key="testSource">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary x:Name="s" Source="pack://application:,,,/ClassLibrary1;component/Buttons.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Grid.Resources>
<Button Template="{DynamicResource RightButton}" Content="TestBtn" HorizontalAlignment="Left" Width="100" Height="100" Margin="474,529,0,0" ></Button>
</Grid>
</UserControl>
When i use Template="{DynamicResource RightButton}" template is not loaded correctly (actually there is no sign of button on screen).
Also there is no error about loading the resourcedictionary.
I couldn't find, what should i use in order to load template on this button. Can anyone help me?

Related

WPF- Compile error on referencing a Resource Dictionary file

Question: When I reference the following Resource Dictionary file in MainWindow.xaml file (shown below), why do I get the following compile error?
CustomWindowStyle resource not found
Remark:
I'm following this article where the Creating A Resource Dictionary File section is also showing the exact procedure that I am using on how to reference Resource Dictionary in MainWindow.xaml
As shown in the image below, VS2019 does CORRECCTLY recognize CustomWindowStyle when I type Style="{StaticResource ....} line in MainWindow.xaml. But at the compile time (as shown in image 2 below), it throws the above error.
I am using .NET Core 3.1. I'm not sure if the issue is related to .NET Core
When typing the line Style="{StaticResource ....} the intellisense correctly shows the option of selecting CustomWindowStyle:
At the compile time, the error shows up:
.
WindowStyle.xaml:
<ResourceDictionary x:Class="WPF_OctDelete.WindowStyle"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WPF_OctDelete">
<Style x:Key="CustomWindowStyle" TargetType="{x:Type Window}">
<Setter Property="WindowChrome.WindowChrome">
<Setter.Value>
<WindowChrome CaptionHeight="30"
CornerRadius="4"
GlassFrameThickness="0"
NonClientFrameEdges="None"
ResizeBorderThickness="5"
UseAeroCaptionButtons="False" />
</Setter.Value>
</Setter>
<Setter Property="BorderBrush" Value="Black" />
<Setter Property="Background" Value="Gray" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<Grid>
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="5,30,5,5">
<AdornerDecorator>
<ContentPresenter />
</AdornerDecorator>
</Border>
<DockPanel Height="30"
VerticalAlignment="Top"
LastChildFill="False">
<TextBlock Margin="5,0,0,0"
VerticalAlignment="Center"
DockPanel.Dock="Left"
FontSize="16"
Foreground="White"
Text="{TemplateBinding Title}" />
<Button x:Name="btnClose"
Width="15"
Margin="5"
Click="CloseClick"
Content="X"
DockPanel.Dock="Right"
WindowChrome.IsHitTestVisibleInChrome="True" />
<Button x:Name="btnRestore"
Width="15"
Margin="5"
Click="MaximizeRestoreClick"
Content="#"
DockPanel.Dock="Right"
WindowChrome.IsHitTestVisibleInChrome="True" />
<Button x:Name="btnMinimize"
Width="15"
Margin="5"
VerticalContentAlignment="Bottom"
Click="MinimizeClick"
Content="_"
DockPanel.Dock="Right"
WindowChrome.IsHitTestVisibleInChrome="True" />
</DockPanel>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
MainWindow.xaml:
<Window x:Class="WPF_OctDelete.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:WPF_OctDelete"
mc:Ignorable="d"
Style="{StaticResource CustomWindowStyle}"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="WindowStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
<Button x:Name="btnTest" Content="Test"/>
</Grid>
</Window>
Your resource is being loaded after the window is loaded and so it cannot find the resource during the window loading event. So your method isn't going to work that way.
You need to put that resource in your App.xaml file, see - How to Set the Source of an Image in XAML and in Code Behind to an image in another project in WPF
In your case (in App.xaml) - '
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="WindowStyle.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
And then you can use your key in the Window -
<Window x:Class="WPF_OctDelete.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:WPF_OctDelete"
mc:Ignorable="d"
Style="{StaticResource CustomWindowStyle}"
Title="MainWindow" Height="450" Width="800">
<!--Rest of your UI Elements-->
</Window>
No need to add resources to your window, since its added to the main app file. That resource will be available across your entire project (available for other windows/controls)
(Edit: further clarification - When you add something as a "StaticResource" to your window style, but load the actual resource later, the window "loaded" event is not going to pick it up. Another solution is to refer your style as "DynamicResource", so the style during the "loaded" event is not static and will be updated when it captures the new resource.)
The XAML processor reads the XAML file from top to bottom so by the time it tries to resolve the CustomWindowStyle resource, it hasn't yet loaded the ResourceDictionary.
You could easily fix this by setting the Resources property before you set the Style property:
<Window x:Class="WPF_OctDelete.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:WPF_OctDelete"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="WindowStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Window.Style>
<StaticResource ResourceKey="CustomWindowStyle"/>
</Window.Style>
<Grid>
<Button x:Name="btnTest" Content="Test"/>
</Grid>
</Window>
The order matters.

Style an activation indicator from material design

I want to style an activation indicator from material design in WPF. I want the styling to happen in an external styling.xaml file, so the textbox I'm using can be binded to that style.
The textbox:
<TextBox materialDesign:HintAssist.Hint="Search:" Grid.Column="1" Margin="35 8 20 5"
Width="200" Style="{"STYLE style"}/>
You could set it as a StaticResource:
File: styling.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:YourNamespace">
<Style TargetType="{x:Type TextBox}" x:key="YourCustomTextBoxStyle">
<Setter Property="Margin" Value="35 8 20 5"/>
....
</Style>
</ResourceDictionary>
In your View (or Application) add a reference to the styling ResourceDictionary and use the style as a static resource:
<UserControl
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:YourNamespace.Wpf"
x:Class="YourView" mc:Ignorable="d">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/YourNamespace;component/Themes/styling.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<TextBox materialDesign:HintAssist.Hint="Search:" Grid.Column="1" Width="200" Style="{StaticResource YourCustomTextBoxStyle}/>
</UserControl>

My Two DataGrid XAML Resources are Mutually Exclusive --- Why?

In order to have a nicer look, I am trying to add to my DataGrid 2 features that I found in separate places, but for some reason they just can't get along.
I can either have the section inside the blue rectangle or the one in the red one.
TIA
Put the <ControlTemplate> tag inside the <ResourceDictionary> tag, underneath the closing </ResourceDictionary.MergedDictionaries> tag.
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Themes\DataGrid.Generic.xaml" />
</ResourceDictionary.MergedDictionaries>
<ControlTemplate x:Key="SelectAllButtonTemplate" TargetType="{x:Type Button}">
<Grid>
<Rectangle x:Name="Border" Fill="LightBlue" SnapsToDevicePixels="True" />
</Grid>
</ControlTemplate>
</ResourceDictionary>
</UserControl.Resources>

WPF Reference control in resourcedictionary

I created my resource dictionary and can access styles in it, but how (If possible) would I reference an entire control from it?
Here's the resourcedictionary:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="MainWindowStyle" TargetType="Window">
<Setter Property="Background" Value="Transparent"></Setter>
<!--Can access this-->
</Style>
<Window x:Key="CustomWindow" Background="Transparent">
<!--Want to access this-->
</Window>
</ResourceDictionary>
Here's the main window xaml file:
<Window x:Class="MyNamespace.MyWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="640" Width="960" >
<!--setting Style={StaticResource MainWindowStyle} adds the style but I want this window to be replaced by the one in the resourcedictionary-->
<Grid>
</Grid>
</Window>
So I basically want to replace the window in the xaml file with the one created in the resource dictionary.
You can certainly host something like a UserControl within another control.
E.g. a ContentControl
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Window x:Key="CustomUserControl" Background="Transparent">
<!--Want to access this-->
</Window>
</ResourceDictionary>
Then:
<ContentControl Content="{StaticResource ResourceKey=CustomUserControl}" />
I suspect that's not quite what you're after, but it's not clear what you may/may not have within the Window that's of interest.

Is it possible to reference a resource dictionary and define a style in the same resource section?

Like so:
<Window x:Class="WpfApplication3.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 x:Key=""whatever" Source="colors.xaml" />
<Style TargetType="Button">
<!- button style using colors defined in colors.xaml -->
</Style>
</Window.Resources>
<StackPanel>
<Button Background="{DynamicResource background1}" Height="50"></Button>
<Button Background="{DynamicResource background2}" Height="50"></Button>
</StackPanel>
</Window>
If I do that I get warnings about background1 and background2 not being resolved and an XamlParseException, because the Resource property of window is already defined (it is not). Everything is fine if I remove the stuff.
Any ideas?
It's easy with MergedDictionaries
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary x:Key=""whatever" Source="colors.xaml" />
</ResourceDictionary.MergedDictionaries>
<Style TargetType="Button">
<!- button style using colors defined in colors.xaml -->
</Style>
</ResourceDictionary>
</Window.Resources>

Resources