0

In my WPF app I'm trying to create a Custom Chrome Window [Ref: WindowChrome]. I followed Restyle Your Window article. I created Resource Dictionary file along with its code-behind in my project, as shown below. I then referenced the resource dictionary in the app.xaml file (also shown below). As you can see, the x:key value of the Style tag in resource dictionary file is CustomWindowStyle. Question: How do I assign the Window the Style CustomWindowStyle?

MyResourceDictionaryWindowStyle.xaml:

<ResourceDictionary x:Class="MyWPFProject.WindowStyle"
                    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:MyWPFProject">

    <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>

MyResourceDictionaryWindowStyle.xaml.cs:

using System;
 .......
using System.Windows;

namespace MyWPFProject
{
    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 == System.Windows.WindowState.Normal)
            {
                window.WindowState = System.Windows.WindowState.Maximized;
            }
            else
            {
                window.WindowState = System.Windows.WindowState.Normal;
            }
        }

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

MainWindow.xaml:

<Window x:Class="MyWPFProject.MainWindow"
        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"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
       <Button x:Name="btnTest" Content="Test" Click="btnTest_Click"/>
       ......
       ......
    </Grid>
</Window>

UPDATE:

App.xaml:

According to user @Simon Stanford's suggestion here: All you have to do is reference the resource dictionary in your app.xaml file and then assign the Window the Style CustomWindowStyle. So I have referenced the Resource Dictionary as follows. Question now is: How do I assign the Window the Style CustomWindowStyle?

<Application x:Class="MyWOFProject.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:MyWOFProject"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <ResourceDictionary Source="MyResourceDictionaryWindowStyle.xaml"/>
    </Application.Resources>
</Application>
nam
  • 21,967
  • 37
  • 158
  • 332
  • Does this answer your question? [How to create custom window chrome in wpf?](https://stackoverflow.com/questions/6792275/how-to-create-custom-window-chrome-in-wpf) – Tom Joney Jul 18 '20 at 20:31
  • @TomJoney The user `@Simon Stanford`'s [response](https://stackoverflow.com/a/44933846/1232087) in your suggested link is almost doing what I have done. But that user is advising: All you have to do is reference the resource dictionary in your app.xaml file `and then assign the Window the Style CustomWindowStyle`. The last part of his advice is what I looking on how to do. Any suggestions? – nam Jul 18 '20 at 22:32
  • 1
    Not really sure what you didn't get from there but it seems as though you have a gap in your knowledge about ResourceDictionaries so I'd recommend having a read of this: https://learn.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/resourcedictionary-and-xaml-resource-references for help regarding the matter and help referencing. – Tom Joney Jul 18 '20 at 22:57
  • @TomJoney Your link provided a general understanding on the subject. But, its sublink [Every FrameworkElement can have a ResourceDictionary](https://docs.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/resourcedictionary-and-xaml-resource-references#every-frameworkelement-can-have-a-resourcedictionary) together a response from `@thatfuy` helped me resolve the issue. Since `Window` is also a `FrameworkElement ` you set its attribute as `Style="{StaticResource CustomWindowStyle}"` as user `@thatguy` shows in his `MainWindow.xaml` code below. Thank you for providing the assistance. – nam Jul 18 '20 at 23:57
  • I am glad you have figured it out - at first, it was hard to interpret what you needed help with so I provided a link that I thought would give you some more understanding. Cheers. – Tom Joney Jul 19 '20 at 00:14

1 Answers1

2

How do I assign the Window the Style CustomWindowStyle?

Merge your MyResourceDictionaryWindowStyle in App.xaml. See the example below. Your project might have a different name than MyWPFProject.App and the Source of the resource dictionary depends on where your custom resource dictionary is actually located in the project, so you should adapt both accordingly, as well as the StartupUri for your main window.

<Application x:Class="MyWPFProject.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>
         <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="pack://application:,,,/MyWPFProject;component/MyResourceDictionaryWindowStyle.xaml"/>
         </ResourceDictionary.MergedDictionaries>
      </ResourceDictionary>
   </Application.Resources>
</Application>

Then just set the style as StaticResource in your window.

<Window x:Class="MyWPFProject.MainWindow"
        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"
        mc:Ignorable="d"
        Style="{StaticResource CustomWindowStyle}"
        Title="MainWindow" Height="450" Width="800">
    <!-- ...your XAML code -->
</Window>
thatguy
  • 21,059
  • 6
  • 30
  • 40
  • I have added an **UPDATE** section with my `App.xaml` file content and a comment. Would that work? – nam Jul 18 '20 at 22:47