How to dynamically add ResourceDictionary to MergedDictionaries in WPF app - c#

I have the next WPF part of code:
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Languages/English.xaml"/>
<ResourceDictionary Source="Languages/Romana.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Page.Resources>
How can I select from code one of those ResourceDictionarys?
EDIT:
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Languages/English.xaml"/>
<ResourceDictionary Source="Languages/Romana.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ScrollViewer HorizontalScrollMode="Auto" HorizontalScrollBarVisibility="Hidden" VerticalScrollMode="Disabled" VerticalScrollBarVisibility="Hidden" BorderThickness="0,3,0,3" BorderBrush="Aqua">
<StackPanel Orientation="Horizontal">
<AppBarToggleButton x:Name="Connect_toggle" Label="{StaticResource connect}" HorizontalAlignment="Stretch" Icon="Accept" VerticalAlignment="Stretch" d:LayoutOverrides="Width" Click="Connect_toggle_Click"/>
<AppBarToggleButton x:Name="Options_toggle" Label="{StaticResource options}" HorizontalAlignment="Stretch" Icon="Accept" VerticalAlignment="Stretch" d:LayoutOverrides="Width" Click="Options_toggle_Click"/>
</StackPanel>
</ScrollViewer>
I did not specify that I am using Windows Universal (VS2015).

You can dynamically select the ResourceDictionary file and add it to MergedDictionaries using C# code-behind like shown in the following code snippet:
// prefix to the relative Uri for resource (xaml file)
string _prefix = String.Concat(typeof(App).Namespace, ";component/");
// clear all ResourceDictionaries
this.Resources.MergedDictionaries.Clear();
// add ResourceDictionary
this.Resources.MergedDictionaries.Add
(
new ResourceDictionary { Source = new Uri(String.Concat(_prefix + "Languages/English.xaml", UriKind.Relative) }
);
where "Languages/English.xaml" is a sample relative path to selected ResourceDictionary file pertinent to your example.
Hope this may help.

Related

Applying PresentationFramework.Royale style to .net 4.8 wpf project

I have a WPF application where I have two stylesheets xaml. But I need to apply base style i.e PresentationFramework.Royale to only one of them, which is not directly loaded in App.xaml.
Below is my App.xaml. I do not want to refer PresentationFramework.Royale here,
<Application
x:Class="UI.Desktop.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/UI.Common;component/Style.Shui.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
I have a login view usercontrol to which i need to add PresentationFramework.Royale as base style along with another stylesheet. How can I achieve this,
<UserControl
x:Class="Views.Implementation.Common.LoginView"
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"
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/PresentationFramework.Royale, Version=3.0.0.0, Culture=Neutral, PublicKeyToken=31bf3856ad364e35, ProcessorArchitecture=MSIL;component/themes/royale.normalcolor.xaml" />
<ResourceDictionary Source="pack://application:,,,/Test.APP.UI.Common;component/Style.Test1.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Button
x:Name="Login"
Grid.Row="4"
Grid.Column="2"
Width="85"
Margin="0,0,15,0"
HorizontalAlignment="Left"
Content="Login"
IsDefault="True"
TabIndex="8"
ToolTip="Login" />
</UserControl>
The issue is above code Style.Test1.xaml controls does not take royale.normalcolor.xaml as base. But it works if I put royale.normalcolor.xaml reference in App.xaml

Resource Dictionary not working - Exception raised for Name/Key not found

I have just started working with Resource Dictionaries and I am stuck on this because my resource dictionary is not working at all. I have tried code-behind and XAML but every time I get exceptions and the app crashes.
If I reference the Dictionary through XAML I get the exception at runtime that Name/Key is not found. The code I used in App.xaml is:
<Application
x:Class="WatchfreeWebsite.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:WatchfreeWebsite.Helpers">
<Application.Resources>
<TransitionCollection x:Key="TransCollection">
<EdgeUIThemeTransition Edge="Right"/>
</TransitionCollection>
<ResourceDictionary x:Key="resourcesDictionary">
<ResourceDictionary.MergedDictionaries>
<local:GlobalTemplates Source="Helpers/GlobalTemplates.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
The resource dictionary holds aDataTemplate and a MediaTransportControlsStyle but I cant seem to reference it through XAML because it gives syntax errors and during the runtime the page produces exception while loading XAML at InitializeComponent(); stage.
Resource Dictionary:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:WatchfreeWebsite.Helpers"
x:Class="WatchfreeWebsite.Helpers.GlobalTemplatesClass"
xmlns:data="using:WatchfreeWebsite.Helpers">
<DataTemplate x:Key="StreamBoxItemTemplate"
x:DataType="data:StreamingHelper">
<TextBlock Text="{x:Bind StreamName, Mode=OneWay}"
Style="{StaticResource BodyTextBlockStyle}"
TextWrapping="NoWrap"
MaxLines="1"
TextTrimming="WordEllipsis"/>
</DataTemplate>
<Style TargetType="MediaTransportControls"
x:Key="myCustomTransportControls">
<Setter Property="IsTabStop" Value="False" />
.......
</Style>
</ResourceDictionary>
The class behind the resource dictionary is:
public partial class GlobalTemplatesClass
{
public GlobalTemplatesClass()
{
this.InitializeComponent();
}
}
I reference the DataTemplate inside the above style and this style is referenced in another page as:
<MediaPlayerElement x:Name="MediaView"
Grid.Row="2"
Source="{Binding MediaSourceObject, Mode=OneWay}"
DoubleTapped="MediaView_DoubleTapped"
AreTransportControlsEnabled="True">
<MediaPlayerElement.TransportControls>
<data:CustomTransportControlsHelper Style="{StaticResource ResourceKey=myCustomTransportControls}"/>
</MediaPlayerElement.TransportControls>
</MediaPlayerElement>
But this is not working and there is a red line below the resource name saying that the resource is not found.
Is there something that I am missing? If someone can help me here please provide your suggestions. Thanks
When you add multiple items under your resources, each of them should fall within the <ResourceDictionary> tag and not directly under <Application.Resources>.
That's because Resources itself is a dictionary, so you're in effect trying to replace that collection rather than add elements to it. Docs here: https://msdn.microsoft.com/en-us/library/system.windows.application.resources%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396
I created a sample project with just an App.xaml at the project base level, a folder called Helpers and a ResourceDictionary under Helpers named GlobalTemplates.xaml to match yours.
Created a simple brush as an example in GlobalTemplates.xaml
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App1.Helpers">
<SolidColorBrush x:Key="DefaultForeground" Color="DarkGreen" />
</ResourceDictionary>
In App.xaml
<Application
x:Class="App1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App1"
RequestedTheme="Light">
<Application.Resources>
<ResourceDictionary>
<TransitionCollection x:Key="TransCollection">
<EdgeUIThemeTransition Edge="Right"/>
</TransitionCollection>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Helpers/GlobalTemplates.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
And then in MainPage.xaml successfully referenced the style from the dictionary:
<Page
x:Class="App1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<TextBlock Foreground="{StaticResource DefaultForeground}">Hello world</TextBlock>
</Grid>
</Page>

WPF - XAML Page Center to Window

I'm building a WPF app using .NET 4.0 and MVVM Light.
I have implemented navigation in the app using a single Window with a Frame that is changing based in my current view.
Here's the code I have in my MainWindow.xaml:
<Controls:MetroWindow x:Class="App.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
xmlns:resx="clr-namespace:App.Resources"
xmlns:utils="clr-namespace:App.Utils"
Title="{Binding Path=Content.Title, ElementName=MainFrame}"
Height="{Binding Source={x:Static SystemParameters.PrimaryScreenHeight}, Converter={utils:RatioConverter}, ConverterParameter='0.9' }"
Width="{Binding Source={x:Static SystemParameters.PrimaryScreenWidth}, Converter={utils:RatioConverter}, ConverterParameter='0.9' }"
xmlns:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks"
WindowStartupLocation="CenterScreen">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/Blue.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
<Frame Source="\Views\LoginView.xaml" NavigationUIVisibility="Hidden" Name="MainFrame"></Frame>
</Grid>
</Controls:MetroWindow>
By default, the MainWindow is occupying the 90% of the screen. I would like to center the contents of the MainFrame inside the MainWindow.
Is it posible? How can I do it? I guess it's a simple task to do, but I've been looking for 1 hour and I couldn't find something specific.
Since you are using a grid, you can insert a stackpanel and center them out, like this:
<Grid VerticalAlignment="Center">
<StackPanel HorizontalAlignment="Center">
<Frame Source="\Views\LoginView.xaml" NavigationUIVisibility="Hidden" Name="MainFrame"></Frame>
</StackPanel>
</Grid>

Telerik RadWindow

I'm facing some issues with Telerik Themes in WPF
I have added reference to Telerik.Windows.Themes.Windows8 and merged the resources using the file App.xaml with the following code:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Telerik.Windows.Themes.Windows8;component/Themes/System.Windows.xaml"/>
<ResourceDictionary Source="/Telerik.Windows.Themes.Windows8;component/Themes/Telerik.Windows.Controls.xaml"/>
<ResourceDictionary Source="/Telerik.Windows.Themes.Windows8;component/Themes/Telerik.Windows.Controls.Navigation.xaml"/>
<ResourceDictionary Source="/Telerik.Windows.Themes.Windows8;component/Themes/telerik.windows.controls.docking.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
Now I want to apply the Windows 8 Style to my main windows, so I changed it to a telerik:RadWindow
<telerik:RadWindow
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
x:Class="Foo.MainWindow"
Header="MainWindow" Height="350" Width="525">
<Grid>
<TextBlock HorizontalAlignment="Left" Margin="37,79,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top"/>
<telerik:RadSlider HorizontalAlignment="Left" Margin="273,156,0,0" VerticalAlignment="Top" Width="200"/>
<telerik:RadButton Content="Button" HorizontalAlignment="Left" Height="Auto" Margin="158,232,0,0" VerticalAlignment="Top" Width="Auto" Click="ButtonBase_OnClick"/>
</Grid>
</telerik:RadWindow>
In the designer the theme is applied and anything looks ok:
but when I start the application it looks totally different:
I have no idea why this error occurs.
If I use the code to create a RadWindow it works perfectly:
RadWindow w = new RadWindow();
w.Width = 500;
w.Height = 500;
w.Show();
I think as you're using implicit styles you need to state that your window style is based on the implicit styles you've imported. Add this inside your RadWindow XAML:
<telerik:RadWindow.Style>
<Style TargetType="telerik:RadWindow" BasedOn="{StaticResource RadWindowStyle}" />
</telerik:RadWindow.Style>
Alternatively add this to your resource dictionary (local:MainWindow should resolve to Foo.MainWindow):
<Style BasedOn="{StaticResource RadWindowStyle}" TargetType="local:MainWindow" />
Here are some links that may prove useful:
http://www.telerik.com/forums/show-radwindow-with-implict-style
http://www.telerik.com/support/kb/wpf/window/details/how-to-use-radwindow-as-main-window

Best way for storing data-string relative to elements

What is the best, most possible, proper way to store data inside elements?
I used to use a separated XML file and now i'm using the Tag and tooltip property.
It's a string-type data, e.g.:
Theme data Theme1.fg.ffffffff;Theme2.fg.ff000000;
Margins according to window size Margin.16:9.10,5,10,5;
With WPF/XAML an ideal approach could be to store such strings in Resources of the respective element or in a ResourceDictionary
eg
<Grid x:Name="myGrid" xmlns:sys="clr-namespace:System;assembly=mscorlib">
<Grid.Resources>
<sys:String x:Key="ThemeData">Theme1.fg.ffffffff;Theme2.fg.ff000000;</sys:String>
<sys:String x:Key="Margins">Margin.16:9.10,5,10,5;</sys:String>
</Grid.Resources>
</Grid>
to use the same you have two approach
xaml approach
<TextBlock Text="{StaticResource ThemeData}" />
code behind
string themeData = myGrid.FindResource("ThemeData");
these resources can also be stored in a ResourceDictionary which can further be merged in any element, window or even whole application
eg
StringResources.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<sys:String x:Key="ThemeData">Theme1.fg.ffffffff;Theme2.fg.ff000000;</sys:String>
<sys:String x:Key="Margins">Margin.16:9.10,5,10,5;</sys:String>
</ResourceDictionary>
usage
<Grid x:Name="myGrid">
<Grid.Resources>
<ResourceDictionary Source="StringResources.xaml" />
</Grid.Resources>
<TextBlock Text="{StaticResource ThemeData}" />
</Grid>
or this if you want to merge/override some more resources
<Grid x:Name="myGrid">
<Grid.Resources>
<ResourceDictionary xmlns:sys="clr-namespace:System;assembly=mscorlib">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="StringResources.xaml" />
</ResourceDictionary.MergedDictionaries>
<!--define new resource or even override existing for this specific element -->
<sys:String x:Key="ThemeData">Theme1.fg.ff00ff00;Theme2.fg.ff0000ff;</sys:String>
<sys:String x:Key="NewMargins">Margin.16:9.10,5,10,5;</sys:String>
</ResourceDictionary>
</Grid.Resources>
<TextBlock Text="{StaticResource ThemeData}" />
</Grid>
The way I understood, you can use Tag property on controls to store the info . it accepts object type. hence you can attach any type to it. like control.Tag = objectyouwantto attach.
if my answer seems not relevant, please elaborate your question

Categories

Resources