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.
Related
I have a file (icons.xaml) that I added as a file in the Resources of my project. The file content is given below:
Icons.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<VisualBrush x:Key="Bucket"
Stretch="Uniform">
<VisualBrush.Visual>
<Viewbox Stretch="xxxx">
<Canvas Width="xxxxx"
Height="xxxx"> and so on...
Icons.xaml file's properties in vs 2017
Now, I want to consume the VisualBrush mentioned above, in my XAML (View) code directly. The lines are given below:
XAML Code (View)
<Setter Property="Icon">
<Setter.Value>
<Rectangle Fill="{Binding Bucket, Source={x:Static resx:Resources.Icons}}"/>
</Setter.Value>
</Setter>
The "resx" namespace is defined as:
xmlns:resx="clr-namespace:MyProjectNamespace.Properties"
When I run my project I cannot see my icons being binded to the rectangle's fill property and I am getting some xaml intellisense error which is "Cannot resolve property "Bucket" in the context of type "string".
Objective: I want to use the visualbrush key directly in the XAML in my Rectangle's Fill property in my View code.
Note: I have a restriction that I cannot use the code in the view which is given below, I cannot use <ResourceDictionary> tab in the xaml code.
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/MyProjectNamespace;component/Resources/Icons.xaml"></ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
Am I following the right approach regarding my objective or should I change this approach?
I have seen the methods that are used here in this answer but none of them are working Get values from *.resx files in XAML
I think the main issue here is that Binding is actually looking for a property called Binding on the Resources.Icons object.
Try this:
<Setter Property="Icon">
<Setter.Value>
<Rectangle Fill="{Binding Bucket, Source={x:Static resx:Icons}}"/>
</Setter.Value>
</Setter>
Binding is not necessary, just try:
<Rectangle Fill="{x:Static resx:Resources.Icons.Bucket}"/>
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}" />
I don't think this has been asked before, if so please redirect me. I'm new to WPF, and I've tried everything I could think of with no success, I'm stuck.
I'm using a WPF Theme, and I want to add some custom styles I created to it. For example, all TextBlock are supposed to have Red foreground, but I have a group of TextBlock that I want in Blue.
So far I've been doing this in the xaml, creating a <Style></Style> in the resources, and calling it using Style="{StaticResource StyleName}". But I want to add it to the theme files instead, and I don't know how to give it a name and call it from the xaml.
I guess I'd start with something like this, but how do I link both elements?
In the theme file (MyStyles.xaml or TextEdit.xaml or similar):
<Style TargetType="{x:Type TextBlock}" x:Key="KeyName" ???>
<Setter Property="Foreground" Value="Blue" />
</Style>
And then in my xaml:
<TextBlock Name="TextBlockName"
Style="{???}">
</TextBlock>
I need this style to be in the Theme because the program will allow users to change themes, and these styles can't hardcoded be in the xaml.
You want to first merge that resource file into your resources :
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="MyStyles.xaml" />
</ResourceDictionary.MergedDictionaries>
<dxc:IntToBooleanConverter x:Key="IntToBooleanConverter" />
(...)
</ResourceDictionary>
</UserControl.Resources>
and then you can use it with
<TextBlock Name="TextBlockName" Style="{StaticResource KeyName}" />
If you have loaded your Theme file you can access any of the Styles/Resources the same way as local Styles/Resources
If you use Style="{StaticResource StyleName}" it will look first in the Window/UserControl, if not found it will look though the loaded Resource dictionaries. so as long as you have loaded the Theme (Resource Dictionary) it will work fine.
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.
I’m having a bit of trouble with resolving resources from an external assembly.
I have a Styles.xaml file in a project called Theme and I have a Default Button style which has been declared as follows:
<Style TargetType="{x:Type Button}" x:Key="{x:Type Button}">
<!--Setters here-->
</Style>
And then in a separate WPF project (but in the same solution) I have the following in the app.xaml file:
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary
Source="/Theme;component/Styles.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
Then in the main Window, I declare a default Button with no style attached to it like so:
<Button Width="100" Height="100" />
In design view, the button appears to pick up the style from the Styles.xaml file, but when I build and run the project, the Button just defaults to the standard button style.
I have checked to see that the Theme.dll file has been copied across to the WPF build directory (and it has) so I don’t know why this is happening.
Interestingly, if I define the Button Style like this
<Style TargetType="{x:Type Button}" x:Key="MyStyle">
And then reference it directly on the Button in the other project like this
<Button Style={StaticResource MyStyle} Width="100" Height="100" />
It picks up the style in design view and works normally when the project is built and executed.
Any ideas? Any help would be great!
Kris
You may need to use a complete pack URI where you reference the XAML file, namely with siteoforigin if you don't reference embedded resources.