WPF Popup - not possible to use DynamicResource - c#

I am using the DropDownButton from the Xceed Wpf Toolkit.
In that popup I just want to display a manually-filled ListView.
A ListViewItem is just a vertical StackPanel with an Image and a TextBlock.
<xceed:DropDownButton Grid.Column="4" x:Name="BurgerButton">
<xceed:DropDownButton.Content>
<Image Source="/Resources/BurgerMenu_128x128.png"/>
</xceed:DropDownButton.Content>
<xceed:DropDownButton.DropDownContent>
<ListView>
<ListViewItem cal:Message.Attach="[Event MouseUp] = [Action NewProject]">
<StackPanel Orientation="Vertical">
<Image Source="/Resources/FileNew_32x32.png"/>
<TextBlock Text="{DynamicResource ProjectSelectorView_NewProject}"/>
</StackPanel>
</ListViewItem>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="DataContext" Value="{Binding DataContext, ElementName=BurgerButton}"/>
</Style>
</ListView.ItemContainerStyle>
</ListView>
</xceed:DropDownButton.DropDownContent>
</xceed:DropDownButton>
I am using Caliburn.Micro to trigger an Action when the MouseUp event of the ListViewItem fires. This works fine. The problem ist the <TextBlock Text="{DynamicResource ProjectSelectorView_NewProject}"/> It is just empty, despite the resource being there. Everywhere else in the project the DynamicResource syntax works fine. It just doesn't work inside the Popup. I know that a Popup doesn't reside in the same VisualTree as the main application - so DataContext sharingis a bit harder.
This isn't about the DataContext though, it is about the ResourceDictionary defined in the App.xaml. my App.xaml looks like this:
<Application x:Class="Projectname"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:CVBRecorder">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Localization/English.xaml"/>
<ResourceDictionary Source="/Localization/German.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
<ResourceDictionary>
<local:AppBootstrapper x:Key="bootstrapper" />
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
Anyone know why the DynamicResource is not displayed inside a WPF popup?

Apparently this is a bug in the Xceed WPF Toolkit. I used version 3.2.0 which had the bug. Updating to 3.4.0 solved the problem.

Related

Is it possible to use a static resource from another dictionary inside a data template?

I have a DataTemplate I'm trying to define and inside of that I have a Button I would like to set the style of. Currently I have a UserControl with MergedDictionaries... probably better to show some code:
<UserControl.Resources>
<ResourceDictionary.MergedDictionaries>
<!-- MyButtonStyle is in this dictionary -->
<ResourceDictionary Source="ms appx:///Dictionaries/ButtonStyles.xaml"/>
<ResourceDictionary>
<DataTemplate x:Key="MyDataTemplate">
<Grid>
<!-- Here is the button I want to apply the style to -->
<Button Style="{StaticResource MyButtonStyle}"/>
</Grid>
</DataTemplate>
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</UserControl.Resources>
I want to set the style of Button inside the DataTemplate to MyButtonStyle which is located in my ButtonStyles.xaml. But I'm getting the following error:
Resource `MyButtonStyle` is not found
How do I correctly reference the resource in my example?
StaticResource will search resources in following order:
All resources that are declared earlier in the same dictionary
Resources in the MergedDictionaries
Application resources
It will not search in the sibling merged dictionaries.
In your case, MyButtonStyle is not included in the ResourceDictionary with MyDataTemplate, nor in any of its MergedDictionaries. What you need is:
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!-- MyButtonStyle is in this dictionary -->
<ResourceDictionary Source="ms appx:///Dictionaries/ButtonStyles.xaml"/>
</ResourceDictionary.MergedDictionaries>
<DataTemplate x:Key="MyDataTemplate">
<Grid>
<!-- Here is the button I want to apply the style to -->
<Button Style="{StaticResource MyButtonStyle}"/>
</Grid>
</DataTemplate>
<ResourceDictionary>
</UserControl.Resources>
#nevermind's commend about the order was very precise. However, in order to import a ResourceDictionary is used the following path
<ResourceDictionary Source="/MyAssemblyName;component/Folder1/Folder2/Res.xaml"></ResourceDictionary>

Unable to resolve resources using separate files

I feel like this is a common sense and trivial, but i don't understand what i'm doing to begin with. I don't have any other resource I can use for help either. Sometimes i wonder if I'm even googling the question right.
I have some custom styles & templates I've made, but now the file is rather large and difficult to work with. I want to put each style or template in there own XAML files (sorta like headers/implementation files) so that a friend could work on one and then we add it to the project. (Such as Dictionary1.xaml ... ). I started a blank project to keep it simple.
Dictionary1.XAML
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary x:Key="SomeKey">
<Color x:Key="detailMark">Black</Color>
<SolidColorBrush x:Key="detailMarkBrush" Color="{StaticResource ResourceKey=detailMark}" />
<Style x:Key="flatTextBox" TargetType="{x:Type TextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid>
<Rectangle Stroke="{StaticResource ResourceKey=detailMarkBrush}" StrokeThickness="1"/>
<TextBox Margin="1" Text="{TemplateBinding Text}" BorderThickness="0"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
App.XAML
<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>
<local:MainWindow x:Key="SomeKey"/>
</Application.Resources>
</Application>
And MainWindow.XAML
<Window x:Class="WpfApplication1.MainWindow"
xmlns:local="clr-namespace:WpfApplication1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow"
Height="350" Width="525">
<Grid>
<TextBox Style="{DynamicResource flatTextBox}"> <!-- doesn't autocomplete/work -->
</TextBox>
</Grid>
</Window>
Edit:
<TextBox Style="{Binding Mode=OneWay, Source={StaticResource SomeKey}}">
<!-- Throws System.Windows.Markup.XamlParseException -->
</TextBox>
As Alex mentioned, the right way to do this is using Merged Dictionaries.
Therefore, you should structure your project correctly, otherwise it will end up in a mess.
Keeping your "blank project", it should look like this:
YourProject
App.xaml (.cs)
MainWindow.xaml (.cs)
SomeOtherWindow.xaml (.cs)
Resources folder
Dictionary1.xaml
Dictionary2.xaml
...
Then you have to decide:
Do you want the resources to be available application wide?
Or do you want the resources to vary between certain windows / user controls?
If you want #1, you have to merge the dictionaries in the App.xaml file:
<Application x:Class=...
...>
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources/Dictionary1.xaml"/>
<ResourceDictionary Source="Resources/Dictionary2.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
If you want #2, you have to merge the dictionaries in the specific window / user control file:
<Window x:Class=...
...>
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources/Dictionary1.xaml"/>
<ResourceDictionary>
<!-- Window specific resources -->
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<!-- Content -->
</Window>

external xaml resource not found by designer when referenced from control template

I have external library libccc with its own resources defined like this:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ccc="clr-namespace:libccc"
>
<ccc:BooleanToHiddenVisibilityConverter x:Key="BooleanToHiddenVisibilityConverter" />
</ResourceDictionary>
In my main project I include it using ResourceDictionary.MergedDictionaries in main app.xaml:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/libccc;component/Resources/Converters.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
Now my problem is that when I reference that resource from Control template only like this:
<window style="{StaticResource MyDialog}">
</window>
where style is defined in application like this:
<ResourceDictionary>
<Style x:Key="MyDialog" TargetType="{x:Type Window}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<Grid>
<Label HorizontalAlignment="Center" Content="{Binding UpdateResultDescription}" Visibility="{Binding UpdateEnded, Converter={StaticResource BooleanToHiddenVisibilityConverter}, FallbackValue=Hidden}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary
VisualStudio Designer throws exception:
Exception: Cannot find resource named 'BooleanToHiddenVisibilityConverter'. Resource names are case sensitive.
My application works as expected, but designer throws exception. When I reference my libccc in other windows that do not use control template then designer works fine.
Anyone can give me a hint what can I change to make designer work?

Setting window background color with XAML

I have a standard XAML styled window in WPF (< Window ....)
In this window I insert a resource dictionary
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Style/Global.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
In the Global.xaml dicionary I have the following code:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="Window">
<Setter Property="Background" Value="Red"/>
</Style>
</ResourceDictionary>
Nothing out of ordinary anywhere. Except it doesn't work, when I compile and run the app, the window background is shown in default white. BUT in the designer tab in Visual Studio where you can see the preview of your window, the background color is correctly changed to red. I don't understand.
I don't have any other styles inserted anywhere that could be overwriting the window's background color.
So how is it possible that in the preview tab it works correctly, but when i actually run the app, it doesn't? What am I doing wrong here?
Here is the entire window code:
<Window x:Class="Apptest.EditBook"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="EditBook" Height="300" Width="300">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Style/Global.xaml" />
<ResourceDictionary Source="Style/Controls.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
</Grid>
</Window>
OK... So this is because your window is actually a type deriving from Window...
public partial class EditBook : Window { }
Target type does not yet work with derived types so you will need to add a key to the style and add it to each window you create that you want to use the style for..
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="Window" x:Key="MyWindowStyle">
<Setter Property="Background" Value="Red"/>
</Style>
</ResourceDictionary>
then you will need to apply the style in the window...
<Window x:Class="Apptest.EditBook"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="EditBook" Height="300" Width="300" Style="{StaticResource MyWindowStyle}">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Style/Global.xaml" />
<ResourceDictionary Source="Style/Controls.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
</Grid>
</Window>
Hope this helps... there is no better solution from what I can see.

ResourceDictionary and Serious Performance Issue

I have two simple ResourceDictionary in my application.
Converters.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:l="clr-namespace:MyApp" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<l:BitmapToBitmapSourceConverter x:Key="BitmapToBitmapSourceConverter"/>
<l:ObjectToVisibilityConverter x:Key="ObjectToVisibilityConverter"/>
</ResourceDictionary>
Styles.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="ComboBoxBase" TargetType="{x:Type ComboBox}">
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Height="16" Margin="0,2,2,2" Source="{Binding Image, Converter={StaticResource BitmapToBitmapSourceConverter}}" VerticalAlignment="Center" Width="16"/>
<TextBlock Text="{Binding}" VerticalAlignment="Center"/>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
When they are merged inside my MainWindow.xaml:
<Window>
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Properties/Converters.xaml"/>
<ResourceDictionary Source="Properties/Styles.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Canvas>
<ComboBox ItemsSource="{Binding Path=Items}" SelectedItem="{Binding Mode=TwoWay, Path=SelectedItem}" Style="{StaticResource ComboBoxBase}"/>
I get an exception when it's time to find BitmapToBitmapSourceConverter inside my Styles.xaml, because it has been defined inside another ResourceDictionary.
Someone suggested me to move my resources from MainWindow.xaml to App.xaml in order to avoid that kind of exceptions. I did it, and suddenly... drama! I don't get anymore that exception, but my application loading time has become 10 times longer. Sometimes it takes more than 5 seconds to show up on my screen, and normally the Window content is plain white for 1 or 2 seconds more.
I tried to run my application from the exe itself, I tried to run it in both Debug and Release mode... nothing. No way to get a good performance after moving my resource files and I can't deliver the application to my customer actually.
Anyone can explain me why and provide a good solution for this?!

Categories