Custom C# WPF Window for seemless results in Windows 7/10

C

Sometimes as developers we have to face the windows versioning problem. Fortunately there are only very few cases where the problem is in the functionality part of our application however this does not apply to the GUI. As you may known already, there is a huge difference in the way that the different versions of windows handle the Graphics. For that reason there are some workarounds you may find in StackoverFlow etc.. to reduce (and usually eliminate) those issues.

In this post we will just give a ready made example to create a seemless WPF window:

Step 1: Copy the following part in your Apps.xaml

    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
            </ResourceDictionary.MergedDictionaries>

            <Style x:Key="CustomWindow" TargetType="{x:Type Window}" >
                <Setter Property="FontFamily" Value="Segoe UI" />
                <Setter Property="TextOptions.TextFormattingMode" Value="Display" />
                <Setter Property="TextOptions.TextRenderingMode" Value="ClearType" />
                <Setter Property="FontWeight" Value="Normal" />
                <Setter Property="FontSize" Value="12" />
                <Setter Property="BorderThickness" Value="1" />
                <Setter Property="BorderBrush" Value="LightGray" />
                <Setter Property="ResizeMode" Value="CanResize" />
                <Setter Property="WindowStyle" Value="None" />
                <Setter Property="UseLayoutRounding" Value="True"/>
                <Setter Property="SnapsToDevicePixels" Value="True"/>
                <Setter Property="WindowChrome.WindowChrome">
                        <Setter.Value>
                        <WindowChrome CaptionHeight="0" ResizeBorderThickness="6" />
                    </Setter.Value>
                </Setter>
            </Style>
            <Style x:Key="WhiteRed" TargetType="{x:Type Button}">
                <Setter Property="SnapsToDevicePixels" Value="True"/>
                <Setter Property="TextOptions.TextFormattingMode" Value="Display" />
                <Setter Property="TextOptions.TextRenderingMode" Value="ClearType" />
                <Setter Property="Background" Value="White"/>
                <Setter Property="Foreground" Value="Black"/>
                <Setter Property="BorderBrush" Value="White"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type Button}">
                            <Border Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}">
                                <ContentPresenter x:Name="PART_Content"
                                          VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                          HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                          TextElement.Foreground="{TemplateBinding Foreground}"/>
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Background" Value="Red"/>
                        <Setter Property="Foreground" Value="White"/>
                        <Setter Property="BorderBrush" Value="Red"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
            <Style x:Key="WhiteGray" TargetType="{x:Type Button}">
                <Setter Property="SnapsToDevicePixels" Value="True"/>
                <Setter Property="TextOptions.TextFormattingMode" Value="Display" />
                <Setter Property="TextOptions.TextRenderingMode" Value="ClearType" />
                <Setter Property="Background" Value="White"/>
                <Setter Property="Foreground" Value="Black"/>
                <Setter Property="BorderBrush" Value="White"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type Button}">
                            <Border Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}">
                                <ContentPresenter x:Name="PART_Content"
                                          VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                          HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                          TextElement.Foreground="{TemplateBinding Foreground}"/>
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Background" Value="LightGray"/>
                        <Setter Property="Foreground" Value="Black"/>
                        <Setter Property="BorderBrush" Value="LightGray"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </ResourceDictionary>
    </Application.Resources>

 

Step 2: Use the following part in your mainWindow.xaml

....
....
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800" 
        Style="{StaticResource CustomWindow}" 
        StateChanged="Window_StateChanged">
    <Grid>
        <Grid Height="31" Margin="0,00,0,0" AllowDrop="True"  VerticalAlignment="Top" Background="White"  MouseLeftButtonDown="titleDoubleClick"   >
            <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
                <Button x:Name="btnMinimize" Content="&#xE949;" Style="{StaticResource WhiteGray}" Width="46" Height="31" Focusable="False" FontSize="11" FontFamily="Segoe MDL2 Assets" Click="btnMinimize_Click"/>
                <Button x:Name="btnMaximize" Content="&#xE739;" Style="{StaticResource WhiteGray}" Width="46" Height="31" Focusable="False" FontSize="10" FontFamily="Segoe MDL2 Assets" Click="btnMaximize_Click"/>
                <Button x:Name="btnClose"    Content="&#xE106;" Style="{StaticResource WhiteRed}"  Width="46" Height="31" Focusable="False" FontSize="10" FontFamily="Segoe MDL2 Assets" Click="btnClose_Click" />
            </StackPanel>
        </Grid>
    </Grid>
</Window>

 

Step 3: Put this final part in your mainWindow.cs

       protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
        {
            base.OnMouseLeftButtonDown(e);
            this.DragMove();
        }

        private void btnClose_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        private void btnMaximize_Click(object sender, RoutedEventArgs e)
        {
            this.WindowState = (this.WindowState == WindowState.Normal) ? WindowState.Maximized : WindowState.Normal;
        }

        private void btnMinimize_Click(object sender, RoutedEventArgs e)
        {
            this.WindowState = WindowState.Minimized;
        }

        private void titleDoubleClick(object sender, MouseButtonEventArgs e)
        {
            if (e.ClickCount == 2)
            {
                this.WindowState = (this.WindowState == WindowState.Normal) ? WindowState.Maximized : WindowState.Normal;
            }
            else
            {
                if (e.LeftButton == MouseButtonState.Pressed)
                {
                    if (this.WindowState == WindowState.Maximized)
                    {
                          this.WindowState = WindowState.Normal;
                          Application.Current.MainWindow.Top = 3;                                   }
                }
            }
        }

        private void Window_StateChanged(object sender, EventArgs e)
        {
            this.BorderThickness = (this.WindowState == WindowState.Maximized) ? new Thickness(8) : new Thickness(1);
            btnMaximize.Content = (this.WindowState == WindowState.Maximized) ? "\xE923" : "\xE739";
        }

 

Tips: You need to install the Segoe UI family (and the Segoe MDL2 in Windows 7)

Disclaimer: The present content may not be used for training artificial intelligence or machine learning algorithms. All other uses, including search, entertainment, and commercial use, are permitted.

Categories

Tags