I have a flyout in my app that I use to add additional contacts into the local database. This flyout is declared as a page resource currently, and does exactly what I need it to, however in order to re-use it on a different page I need to copy both the xaml for the flyout and any attatched events to each page that would require using it (there are several places where a contact might need to be added)
Is there a way to globally define a flyout such that I only need to reference it rather than hardcode it each time? I considered using a ContentDialog (as that can be defined as its own module) but I don't think that would be the right fit
If creating completely in code is not an option you can create a ResourceDictionary with a class in background. First the Styles.xaml:
<ResourceDictionary
x:Class="MyClass.Styles"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Flyout x:Key="MyFlyout">
<!-- my flyout code -->
</Flyout>
</ResourceDictionary>
The important thing here is x:Class, where the value needs to be the namespace+name of the related class we're creating now (Styles.cs in that case):
namespace MyClass {
public partial class Styles {
public Styles() {
this.InitializeComponent();
}
// my events from flyout
}
}
Make sure that the class is declared as partial and calls this.InitializeComponent() in the constructor.
Now in your app resources add a reference:
<Application
...
xmlns:myClass="using:MyClass">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<myClass:Styles />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
Then you can access the Flyout as a static resource, e.g.:
<Button Flyout="{StaticResource MyFlyout}" />
Related
I created a Window style (WPF) and added it as a dll to my project
this style shows corretly when i run the program but doesn't show up in the designer.
I googled already but none of the solutions there are working
Test 1:
// Window //
Style="{DynamicResource HVE_Window}"
// Window.Resources //
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/GlobalHive.Styles;component/HiveWindow.xaml"/>
</ResourceDictionary.MergedDictionaries>
Result:
Error: 'Window' TargetType doesn not match type of element 'WindowInstance'
-> But it runs and display correctly there
Test 2:
// Window //
Style="{DynamicResource MyWindow}"
// Window.Resources //
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/GlobalHive.Styles;component/HiveWindow.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style x:Key="MyWindow" TargetType="{x:Type Window}" BasedOn="{StaticResource HVE_Window}" />
Result:
No Error:
Still doesn't display in the designer, still shows up if i run the program
Test 3:
Both versions but added to application resources
How it should look:
How it looks inside the designer:
You can sometimes find that resources from a control library are not loaded at design time, despite whatever you put in app.xaml to try and load the things.
MS created a mechanism for Blend which you can use in visual studio since it's the blend designer.
This uses a "special" resource dictionary called DesignTimeResources.xaml
This will only be used at design time.
Add one to the Properties of your problem exe project.
With exactly that name.
Put all your merges into that.
eg this is one of mine from my MapEditor project that uses numerous resources from UILib. UILib is a control library with all sorts of UI stuff in it.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MapEditor">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/UILib;component/Resources/Geometries.xaml"/>
<ResourceDictionary Source="pack://application:,,,/UILib;component/Resources/ControlTemplates.xaml"/>
<ResourceDictionary Source="pack://application:,,,/UILib;component/Resources/FontResources.xaml"/>
<ResourceDictionary Source="pack://application:,,,/UILib;component/Resources/UILibResources.xaml"/>
<ResourceDictionary Source="/Views/Drawing/Terrain/Resources/CityResources.xaml"/>
<ResourceDictionary Source="/Resources/MapEditorResources.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
Unload your csproj ( right click in solution explorer), edit it and find the node for that resource dictionary.
Change it to:
<Page Include="Properties\DesignTimeResources.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
<ContainsDesignTimeResources>true</ContainsDesignTimeResources>
</Page>
Reload the project, close and re-open visual studio.
Your styles should now apply.
I have a c# wpf-based class library with models, view models, and views, which I am using in multiple add-ins for dektop applications that have APIs which support hosted dockable WPF user controls. From here I can use different controls and launch dialogs to interact with various data structures in the 3rd-party application. My class library doesn't have an App.xaml file.
I have created a ResourceDictionary xaml file that I am using as a main style sheet throughout my views. In my user controls and windows, I reference it:
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../Resources/styleMain.xaml"/>
</ResourceDictionary.MergedDictionaries
Inside of this style sheet, I manage my various controls to simplify and unify my views. At the lowest level, I have settings for things like font size, font family, and color. For example, I have several brushes that I use throughout my controls. One looks like this:
<Color x:Key="ColorBase_Primary" R="255" G="0" B="115" A="255"/>
<SolidColorBrush x:Key="Color_Primary" Color="{StaticResource ColorBase_Primary}"/>
This all works great for design and testing. However, I am referencing this class library in multiple other projects. In these other projects, I am hosting the main user control from my class library:
<UserControl x:Class="MyAppHost.ucDockingHost"
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:MyAppHost"
xmlns:viewModels="clr-namespace:MyClassLibrary.ViewModels;assembly=MyClassLibrary"
xmlns:views="clr-namespace:MyClassLibrary.Views;assembly=MyClassLibrary"
mc:Ignorable="d">
<UserControl.DataContext>
<viewModels:vmMain/>
</UserControl.DataContext>
<Grid>
<views:ucMainGrid ViewModelMain="{Binding}" Property1="SomeValue" Property2="SomeOtherValue"/>
</Grid>
</UserControl>
Here I am setting DependencyProperties from the add-in application that references my class library without any problems, and all of my bindings and control behaviors are working great.
What I am now hoping to do is be able to specify from my add-in (and not the main class library) the basic resource values that are used throughout my style sheet, especially color (as in being able to change the value associated with x:Key="ColorBase_Primary"). This way, I can adapt different implementations to the branding of different clients, etc. I have been searching for a long time for any examples or insight and keep coming up short.
It would be easy enough to simply deploy the entire class library independently with each application and adjust the style sheet directly, but that doesn't seem right at all. Is there some way for me to create a ResourceDictionary in my add-in applications that could supply, modify or and/override the resource values specified in my class library? Or should I do it through a DependencyProperty in my view model? That doesn't seem right either.
Do not use the MergedDictionaries in your library, i.e. remove this:
In your application, you then merge all resource dictionaries from your library in the correct order:
<Application x:Class="WpfApplication1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/WpfControlLibrary1;component/Brushes.xaml"/>
<ResourceDictionary Source="pack://application:,,,/WpfControlLibrary1;component/Controls.xaml"/>
</ResourceDictionary.MergedDictionaries>
<SolidColorBrush x:Key="brush">Red</SolidColorBrush>
</ResourceDictionary>
</Application.Resources>
</Application>
You can then simply override any resource you want by defining another resource with the same x:Key like I have done with the SolidColorBrush above. This resource overrides any resource with an x:Key of "brush" defined in either Brushes.xaml or Controls.xaml.
I have a resources file Grids.xaml
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Label x:Key="SomeTestLabel">Hello There</Label>
<Grid x:Key="HomeGrid">
<Label Content="{StaticResource SomeTestLabel}"></Label>
</Grid>
</ResourceDictionary>
And in my Menus.xaml file I have
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<TabItem x:Key="HomeTab" Header="Home">
<Grid><!-- PROBLEM IS RIGHT HERE --></Grid>
</TabItem>
</ResourceDictionary>
Is it possible to link <Grid><!-- PROBLEM IS RIGHT HERE --></Grid> with <Grid x:Key="HomeGrid">...</Grid>?
Is there a better View I could use?
Is there a better way to do this?
The main reason I'm doing this is to refactor code out of one file (MainWindow.xaml) and into various other files, so that the main file and main resources file don't get cluttered with random pieces of code
A <ResourceDictionary /> is not ment to be a central place to declare controls. Things that are declared in one of those dictionaries is ment to be used by controls (e.g. styles, brushes, themes, common images, converters and templates).
However, control declarations (e.g. a <Grid />) is always an instance of that particular class that will be rendered by the WPF framework. A control can only exist at one place at a time, therefore, placing one inside a ResourceDictionary is not a good idea (it's not reusable anyway). Control declarations always belong inside the UserControl, Window or other hosting control where you want it to be displayed.
please forgive me in advance. First question.
I am working on a WPF project where I have defined a simple resource dictionary at the application level.
<Application x:Class="Game.UI.Modals.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary Source="GameResources.xaml"></ResourceDictionary>
</Application.Resources>
The reference to the ResourceDictionary is working fine; I am able to utilize it in XAML with no issues.
The problem I am having is in trying to add templates to the dictionary using the Create ControlTemplate Resource tool (right click => edit template => create empty). The Resource dictionary radio button in the define in panel is grayed out.
I have tried creating dictionaries in different namespaces, I made sure the dictionary is named and that the build action is set to resource.
Any idea how to get the Create ControlTemplate Resource dialog to recognize my application level ResourceDictionary?
Thanks!
Include your GameResources.xaml like this instead:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="GameResources.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
The create template dialog lists the merged dictionaries. When you include your resources as in my example, the radiobutton should become enabled and your merged dictionary should appear in the list.
I would like to know exactly how to dynamically use a Dictionary Resource in the C# code behind - ie.. I would like to load images at runtime from an image resource within a dictionary
I have a program that has 3 images in a WPF Dictionary - these are images set as image resources.
Then in the code behind of my WPF Window I want to load any one of the three images based on user initiated events.
There is no real code I have to show as nothing that I have done works.
Ideas?
First, make sure you've defined your image resources like this:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ImageSource x:Key="image1">images/image1.jpg</ImageSource>
<ImageSource x:Key="image2">images/image2.jpg</ImageSource>
</ResourceDictionary>
Secondly, I'm assuming that your WPF dictionary is in its own file. Now you have to make sure you've merged your dictionary into your main window's XAML (skip this step if your resource dictionary is defined inside of the window's XAML). In your window's XAML file, make sure you have something like this:
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="myDictionary.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
Now, in your code-behind, you can use the FindResource() method to locate your image resource by it's key name (the value of the x:Key attribute on the ImageSource in the resource dictionary) like so:
imageControl.Source = (ImageSource)FindResource("image1");
Hope this helps!
This is an addition to the accepted answer:
When working within a ViewModel from MVVM, make sure to use the FindResource from the view where the resource directory is added.
<Window x:Class="My.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ViewModels="clr-namespace:My.ViewModels"
Title="USA Hockey Player Evaluation tool"
Icon="/USAHockeyPlayerEval;component/View/Images/HET.ico"
SizeToContent="WidthAndHeight"
MinHeight="500px" MinWidth="800px">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Images.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Window.DataContext>
<ViewModels:MainWindowMV/>
</Window.DataContext>
<StackPanel>
<Menu>
<MenuItem Header="File">
<MenuItem Header="Save"></MenuItem>
My view in this case is a window (I know not correct MVVM ;-) )
Image img = new Image();
img.Source = (ImageSource)WindowReference.FindResource("Pluse");
Here the WindowReference is a reference to My.MainWindow.