Home > OS >  System.Windows.Markup.XamlParseException:''Provide value on 'System.Windows.StaticRes
System.Windows.Markup.XamlParseException:''Provide value on 'System.Windows.StaticRes

Time:02-05

I am trying to apply a style to a particular WPF Window in my application, not to all window. Basically I want to change the style just because I want the window header bar to look different. I have seen that starting from net Framework 4.5 there is a WindowChrome class which allows to customize the window frame and the title bar without touching the functionality (standard window behaviors: resizing, moving, etc.).

So I have found this interesting article where it explains how to do it.

It consists on creating a dictionary resource file (.xaml):

<ResourceDictionary x:Class="myApp.Styles.WindowStyle"
                    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">


    <Style x:Key="CustomWindowStyle" TargetType="{x:Type Window}">
        <Setter Property="WindowChrome.WindowChrome">
            <Setter.Value>
                <WindowChrome CaptionHeight="30"
                              CornerRadius="4"
                              GlassFrameThickness="0"
                              NonClientFrameEdges="None"
                              ResizeBorderThickness="5"
                              UseAeroCaptionButtons="False" />
            </Setter.Value>
        </Setter>
        <Setter Property="BorderBrush" Value="Black" />
        <Setter Property="Background" Value="Gray" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Window}">
                    <Grid>
                        <Border Background="{TemplateBinding Background}"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="5,30,5,5">
                            <AdornerDecorator>
                                <ContentPresenter />
                            </AdornerDecorator>
                        </Border>

                        <DockPanel Height="30"
                                   VerticalAlignment="Top"
                                   LastChildFill="False">

                            <TextBlock Margin="5,0,0,0"
                                       VerticalAlignment="Center"
                                       DockPanel.Dock="Left"
                                       FontSize="16"
                                       Foreground="White"
                                       Text="{TemplateBinding Title}" />

                            <Button x:Name="btnClose"
                                    Width="15"
                                    Margin="5"
                                    Click="CloseClick"
                                    Content="X"
                                    DockPanel.Dock="Right"
                                    WindowChrome.IsHitTestVisibleInChrome="True" />


                            <Button x:Name="btnRestore"
                                    Width="15"
                                    Margin="5"
                                    Click="MaximizeRestoreClick"
                                    Content="#"
                                    DockPanel.Dock="Right"
                                    WindowChrome.IsHitTestVisibleInChrome="True" />

                            <Button x:Name="btnMinimize"
                                    Width="15"
                                    Margin="5"
                                    VerticalContentAlignment="Bottom"
                                    Click="MinimizeClick"
                                    Content="_"
                                    DockPanel.Dock="Right"
                                    WindowChrome.IsHitTestVisibleInChrome="True" />
                        </DockPanel>

                    </Grid>

                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

and attached to its code behind (xaml.cs) so Visual Studio treats it as a code behind file for the resource file.

using System.Windows;

namespace myApp.Styles
{
    public partial class WindowStyle : ResourceDictionary
    {
        public WindowStyle()
        {
            InitializeComponent();
        }

        private void CloseClick(object sender, RoutedEventArgs e)
        {
            var window = (Window)((FrameworkElement)sender).TemplatedParent;
            window.Close();
        }

        private void MaximizeRestoreClick(object sender, RoutedEventArgs e)
        {
            var window = (Window)((FrameworkElement)sender).TemplatedParent;
            if (window.WindowState == WindowState.Normal)
            {
                window.WindowState = WindowState.Maximized;
            }
            else
            {
                window.WindowState = WindowState.Normal;
            }
        }

        private void MinimizeClick(object sender, RoutedEventArgs e)
        {
            var window = (Window)((FrameworkElement)sender).TemplatedParent;
            window.WindowState = WindowState.Minimized;
        }
    }
}

Now I am trying to apply that style to my particular WPF Window (not to all windows) as below.

myDialogView.xaml :

<Window x:Class="myApp.Views.myDialogView"
        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:v="clr-namespace:myApp.Views"
        xmlns:vm="clr-namespace:myApp.ViewModels"
        mc:Ignorable="d" 
        d:DesignHeight="450" d:DesignWidth="800"
        ResizeMode="NoResize"
        SizeToContent="WidthAndHeight"
        Style="{StaticResource CustomWindowStyle}" 
        WindowStyle="None">
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="pack://application:,,,/pEp;component/Resources/Styles/WindowStyle.xaml" />
            </ResourceDictionary.MergedDictionaries>
            <DataTemplate DataType="{x:Type vm:myViewModel1}">
                <v:myView1 />
            </DataTemplate>
            <DataTemplate DataType="{x:Type vm:myViewModel2}">
                <v:myView2 />
            </DataTemplate>
        </ResourceDictionary>
    </Window.Resources>
</Window>

The style is applied correctly to my Window in design time but when I execute it the following exception is thrown in runtime in the constructor when calling InitializeComponent() when I try to open that window:

myDialogView.xaml.cs:

namespace myApp.Views
{
    public partial class myDialogView : Window
    {
        public myDialogView()
        {
            InitializeComponent();
        }
    }
}

Inner Exception: Exception: Cannot find resource named 'CustomWindowStyle'. Resource names are case sensitive.

To open my WPF Window I simply do:

var myWindow = new myApp.Views.myDialogView();
myWindow.DataContext = new myApp.ViewModels.myDialogViewModel();
myWindow.ShowDialog();

CodePudding user response:

The resource being inside window tags will be loaded after it's referenced. Xaml is turned into controls top to bottom, outside tags to inside.

You may either merge the resource dictionary in app.xaml.

Or

Try using it as a Dynamicresource instead of static resource.

  • Related