Style defined in ResourceDictionary referencing a template within the same ResourceDictionary - wpf

I have created a ResourceDictionary in my WPF application like so:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:local="clr-namespace:WpfRibbonApplication1"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:vsm="http://schemas.microsoft.com/netfx/2007/xaml/presentation" >
</ResourceDictionary>
Inside of this resource dictionary I have defined a style for my custom textbox control like so:
<Style TargetType="{x:Type local:SimpleSwingTextBox}" x:Key="SimpleSwingTextBoxStyle">
</style>
Within the style is a tooltip:
<ToolTip x:Name="validationTooltip" Template="{StaticResource ValidationToolTipTemplate}">
</Tooltip>
Also within the same ResourceDictionary I have the template referenced above in the style:
<ControlTemplate x:Key="ValidationToolTipTemplate">
</ControlTemplate>
Then in my C# code, I create an instance of my custom text box control and set its style to the style defined in the resource dictionary:
SimpleSwingTextBox textBox = new SimpleSwingTextBox(textPoint);
Uri resourceLocator = new Uri("Assets/SimpleSwingResourceDictionary.xaml", System.UriKind.Relative);
ResourceDictionary rd = (ResourceDictionary)Application.LoadComponent(resourceLocator);
textBox.Style = rd["SimpleSwingTextBoxStyle"] as Style;
The problem I have is that an exception is immediately thrown which has the following message:
"Cannot find resource named 'ValidationToolTipTemplate'. Resource names are case sensitive."
I don't understand how the style I created cannot find the 'ValidationToolTipTemplate' when they are in the same ResourceDictionary xaml file?
Can anyone see what I am doing wrong here? Thanks

Related

WPF - how to reference a style in a resource when the resource dictionary has a key set

I have created a user control that needs to reference an external resource dictionary file. A style within this resource file is then used against a textbox in the user control.
The external resource dictionary file is as follows:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="ValidatedTextboxStyle" TargetType="{x:Type TextBox}">
...
</Style>
I then import this into the user control as follows: (with the long file location removed)
<Control.Resources>
<ResourceDictionary x:Key="Test" Source="..." />
<common:StringCollapseVisibilityConverter x:Key="StringCollapseVisibilityConverter" />
</Control.Resources>
The WPF designer forces me to give it a "key" due to the other resource that is referenced.
Without the dictionary having a name, you would normally reference it like:
Style="{StaticResource ValidatedTextboxStyle}"
How would I reference the style that has name "ValidatedTextboxStyle" within the external resource file taking into account that the imported resource dictionary is given the key name "Test"?
Merged the dictionary in your control and you can use it like earlier via StaticResource.
<Control.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="..." />
</ResourceDictionary.MergedDictionaries>
<common:StringCollapseVisibilityConverter
x:Key="StringCollapseVisibilityConverter" />
</ResourceDictionary>
</Control.Resources>
Also, you can omit setting x:Key now on resource dictionary since all the defined resources in resource dictionary are merged into your control resources.
Now, you can use like earlier:
Style="{StaticResource ValidatedTextboxStyle}"

WPF Controls as StaticResource in Resource Dictionary, used in multiple WPF Windows?

I have a Button control as a resource in Resource Dictionary as below:
<!--ButtonResources.xaml file-->
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Button x:Key="buttonResource" Content={Binding BoundText}/>
</ResourceDictionary>
<!--ButtonResources.xaml file-->
I now use this above button control bound to Content property of ContentControl controls in 2 different Windows .xaml files where each Window has its own DataContext and thus each window should display the Content of above button control based on its ViewModel's BoundText property value as below for each Window.
<Window x:Class="TestClass1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ButtonResources.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
<ContentControl Content={StaticResource buttonResource}/>
</Grid>
</Window>
But, the problem is that both Window's display same value for the BoundText property which means that both the WPF Windows have same instance of button control from resource, used in both the Windows.
How can I resolve this problem such that each Window gets a separate button control from the resource and still display different values for the BoundText property from their own ViewModel?
Edit:
For the reason mentioned in MSDN as below, I can't use x:Shared="False" attribute to resolve this:
•The ResourceDictionary that contains the items must not be nested
within another ResourceDictionary. For example, you cannot use
x:Shared for items in a ResourceDictionary that is within a Style that
is already a ResourceDictionary item.
Did you try to use the x:Shared attribute?
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Button x:Shared="False" x:Key="buttonResource" Content={Binding BoundText}/>
</ResourceDictionary>
For more info read here.
In case this does not work, you can store a template in your resource, instead of the button and use a ContentControl inside your window to display it.
Try:<Style TargetType="Button" x:Key="buttonResource">
<Setter Property="Content" Value="{Binding BoundText}" />
</Style>
<Button Style="{StaticResource buttonResource}" />

Set window icon in style

I would like to use the same icon for my main window and for any dialogs or message boxes whithin my application, so I tried to set it like this in a ResourceDictionary:
<Style TargetType="{x:Type Window}">
<Setter Property="Icon" Value="pack://application:,,,/MyReferenceAssemblyName;component/Images/myIcon.gif"></Setter>
</Style>
But that does not work.
How could I share the same icon with the different windows?
Edit:
I have a simple resource dictionary (Style.xaml) where I am defining some global settings. I use it in my App.xaml like this:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources/ViewModelTemplates.xaml"/>
<ResourceDictionary Source="Resources/Style.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
The file contains some definitions like e.g. button height, text box foreground color, etc.
There is no problem with those and all the panels and window my application creates use these settings. That is why I would like the icon to be defined there as well, to have it used allover the application.
I am not looking for a way to set the icon of the .exe file.
Edit:
I have not found the solution for what I want to do, so I ended up creating a BitmapImage in my ResourceDictionary and use it as DynamicResource in each of my Window-Classes.
<BitmapImage x:Key="ApplicationIcon" UriSource="pack://application:,,,/MyReferenceAssemblyName;component/Images/myIcon.gif"></BitmapImage>
and
<Window ...
Closing="Window_Closing"
Title="{Binding Title, UpdateSourceTrigger=PropertyChanged}"
IsEnabled="{Binding IsEnabled, FallbackValue=True, Mode=OneWay}"
WindowState="Maximized"
Icon="{DynamicResource ApplicationIcon}">
...
</Window>
For others that come across this issue, as I had the same one, see a similar question which provides a bit more of an explanation to why this doesn't work.
How to set default WPF Window Style in app.xaml?
There's also a couple of suggestions; one being tabina's solution and to apply the style to each Window separately. It includes an interesting approach to deriving the Window class, but it's down to personal preference, as they're only work-arounds.

WPF - Custom Window not working

I am trying to start building a Custom Window in WPF. I thought I had all the starting pieces in place, but so far, all I get is a regular Window with black content. I assume this is because it's not recognizing my template as the default one for the control.
Can you please let me know what I am missing? Here's my code:
namespace BaseWindowLibrary
{
public class BaseWindow: Window
{
public BaseWindow()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(BaseWindow),
new FrameworkPropertyMetadata(
typeof(BaseWindow)));
}
}
}
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:base="clr-namespace:BaseWindowLibrary">
<ControlTemplate x:Key="BaseWindowTemplate" TargetType="{x:Type base:BaseWindow}">
<Border BorderBrush="Blue" BorderThickness="3" Background="Coral" Width="100" Height="100"/>
</ControlTemplate>
<Style TargetType="{x:Type base:BaseWindow}">
<Setter Property="Template" Value="{StaticResource BaseWindowTemplate}"/>
</Style>
</ResourceDictionary>
Are you defining this xaml code in generic.xaml or in some other resource dictionary and then merging it in generic.xaml?
It's a requirement to have the style the default style.
Also, if you have been adding things by hand, check if VS aded the ThemeInfo attribute in AssemblyInfo.cs.
And if that doesn't work, you should post the code where you declare the window you use (the part in window.xaml or whichever name you use).
EDIT
To clarify, generic.xaml MUST be in the Themes folder of your solution and contain (directly or indirectly) the code for the style.
Looks like you havent included the ResourceDictionary in to your application. Add it to the App.xaml
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="YourResource.xaml" />
</ResourceDictionary.MergedDictionaries>
UPDATE based on the comment:
I tried this BaseWindow:Window as a custom control and it just worked. The Style will be inside Generic.XAML of the custom control library.

How to style a XAML window with a ResourceDictionary that exist in a DLL?

Hi I am trying to create a reusable XAML Window in a DLL.
I have placed in the Themes folder a new ResourceDictionary (I even merged it in the Generic.xaml), but when I try to use its styles in the window, I get an error message that the style doesn't exist:
<Window Style="{StaticResource ModalWindowStyle}" >
<!-- I have also the following -->
<Window.Resources>
<Style TargetType="Button" BasedOn="{StaticResource ButtonStyle}" />
</Window.Resources>
</Window>
I get an exception that this styles don't exist, they are both declared in that ResourceDictionary which is in the Themes folder.
From this post:
... as long as Project B has a reference to Project A.
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Project A;component/YourSubFolder/YourResourceFile.xaml" />
</ResourceDictionary.MergedDictionaries>
Then you can just use the Resources defined in YourResourceFile.xaml.

Resources