webentwicklung-frage-antwort-db.com.de

Wie erstelle ich ein benutzerdefiniertes Fenster chrome in wpf?

Wie kann ich ein einfaches benutzerdefiniertes Fenster erstellen chrome für ein WPF-Fenster, das nicht die Schaltfläche zum Schließen und dennoch ein verschiebbares und in der Größe veränderbares Fenster enthält?

38
Carl Weis

Sie setzen den WindowStyle="None" Ihres Fensters und erstellen dann Ihre eigene Fensteroberfläche. Sie müssen Ihre eigenen Min/Max/Close/Drag-Ereignishandler einbauen, die Größenänderung wird jedoch beibehalten.

Beispielsweise:

<Window 
    WindowState="Maximized" 
    WindowStyle="None"
    WindowStartupLocation="CenterScreen"
    MaxWidth="{Binding Source={x:Static SystemParameters.WorkArea}, Path=Width}"
    MaxHeight="{Binding Source={x:Static SystemParameters.WorkArea}, Path=Height}"
>

    <DockPanel x:Name="RootWindow">
        <DockPanel x:Name="TitleBar" DockPanel.Dock="Top">
            <Button x:Name="CloseButton" Content="X"
                    Click="CloseButton_Click"                 
                    DockPanel.Dock="Right" />
            <Button x:Name="MaxButton" Content="Restore" 
                    Click="MaximizeButton_Click"
                    DockPanel.Dock="Right" />
            <Button x:Name="MinButton" Content="Min"
                    Click="MinimizeButton_Click"
                    DockPanel.Dock="Right" />

            <TextBlock HorizontalAlignment="Center">Application Name</TextBlock>
        </DockPanel>

        <ContentControl Content="{Binding CurrentPage}" />
    </DockPanel>

</Window>

Und hier ist ein Code-Behind-Beispiel für allgemeine Fensterfunktionen

/// <summary>
/// TitleBar_MouseDown - Drag if single-click, resize if double-click
/// </summary>
private void TitleBar_MouseDown(object sender, MouseButtonEventArgs e)
{
    if(e.ChangedButton == MouseButton.Left)
        if (e.ClickCount == 2)
        {
            AdjustWindowSize();
        }
        else
        {
            Application.Current.MainWindow.DragMove();
        }
 }

/// <summary>
/// CloseButton_Clicked
/// </summary>
private void CloseButton_Click(object sender, RoutedEventArgs e)
{
   Application.Current.Shutdown();
}

/// <summary>
/// MaximizedButton_Clicked
/// </summary>
private void MaximizeButton_Click(object sender, RoutedEventArgs e)
{
    AdjustWindowSize();
}

/// <summary>
/// Minimized Button_Clicked
/// </summary>
private void MinimizeButton_Click(object sender, RoutedEventArgs e)
{
    this.WindowState = WindowState.Minimized;
}

/// <summary>
/// Adjusts the WindowSize to correct parameters when Maximize button is clicked
/// </summary>
private void AdjustWindowSize()
{
    if (this.WindowState == WindowState.Maximized)
    {
        this.WindowState = WindowState.Normal;
        MaximizeButton.Content = "1";
    }
    else
    {
        this.WindowState = WindowState.Maximized;
        MaximizeButton.Content = "2";
    }

}
58
Rachel

. NET 4.5 hat eine neue Klasse hinzugefügt, die dies erheblich vereinfacht.

Mit der WindowChrome-Klasse können Sie Windows Presentation Foundation (WPF) -Inhalte in den Nicht-Client-Bereich eines Fensters erweitern normalerweise für den Fenstermanager des Betriebssystems reserviert.

Sie finden ein Tutorial hier .

Und hier ist ein kurzes Beispiel .

43
dss539

Ich habe gerade das folgende Beispiel für .net 4.5 verwendet und es funktioniert sehr gut. Interessanterweise wird ein Code für ein Ressourcenwörterbuch für die Klickereignisse verwendet. Sie müssen lediglich auf das Ressourcenwörterbuch in Ihrer app.xaml - Datei verweisen und dem Fenster den Stil CustomWindowStyle zuweisen. Dies wurde schamlos gestohlen von http://www.eidias.com/blog/2014/1/27/restyle-your-window .

<ResourceDictionary x:Class="WpfApp7.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>

                        <Grid Height="30"
                            VerticalAlignment="Top">

                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="*"/>
                                <ColumnDefinition Width="Auto"/>
                            </Grid.ColumnDefinitions>

                            <StackPanel Orientation="Horizontal" Margin="5,0">
                                <Button Content="A" Margin="0,0,5,0" VerticalAlignment="Center" Click="Button_Click" WindowChrome.IsHitTestVisibleInChrome="True"/>
                                <Button Content="B" Margin="0,0,5,0" VerticalAlignment="Center" Click="Button_Click" WindowChrome.IsHitTestVisibleInChrome="True"/>
                                <Button Content="C" Margin="0,0,5,0" VerticalAlignment="Center" Click="Button_Click" WindowChrome.IsHitTestVisibleInChrome="True"/>
                                <Button Content="D" Margin="0,0,5,0" VerticalAlignment="Center" Click="Button_Click" WindowChrome.IsHitTestVisibleInChrome="True"/>
                            </StackPanel>


                            <TextBlock Margin="5,0,0,0"
                                       VerticalAlignment="Center"
                                       HorizontalAlignment="Center"
                                       FontSize="16"
                                       Foreground="White"
                                       Text="{TemplateBinding Title}" 
                                       Grid.Column="1"/>


                            <StackPanel Orientation="Horizontal"
                                        Grid.Column="2">
                                <Button x:Name="btnClose"
                                    Width="15"
                                    Margin="5"
                                    Click="CloseClick"
                                    Content="X"
                                    WindowChrome.IsHitTestVisibleInChrome="True" />


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

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

                    </Grid>

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

Und für den Code dahinter:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace WpfApp7
{
    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;
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show("Hello!");
        }
    }
}
5
Simon Stanford

Hier ist eine einfache Lösung, die den Standardschaltflächen von Windows 10 sehr ähnlich ist. Sie verwendet einfach dieselbe Schriftart für die Symbole:

<StackPanel Orientation="Horizontal" VerticalAlignment="Top" WindowChrome.IsHitTestVisibleInChrome="True">
<Button Click="Minimize_Click" Content="&#xE949;" FontFamily="Segoe MDL2 Assets" FontSize="10" Padding="15,15,15,5" Background="Transparent" BorderBrush="Transparent" />
<Button Click="Maximize_Click" FontFamily="Segoe MDL2 Assets" FontSize="10" Padding="15,10" Background="Transparent" BorderBrush="Transparent">
    <Button.Style>
        <Style TargetType="{x:Type Button}">
            <Setter Property="Button.Content" Value="&#xE739;" />
            <Style.Triggers>
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}, Path=WindowState}" Value="Maximized">
                    <Setter Property="Button.Content" Value="&#xE923;" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Button.Style>
</Button>
<Button Click="Close_Click" Content="&#xE106;" FontFamily="Segoe MDL2 Assets" FontSize="10" Padding="15,10" Background="Transparent" BorderBrush="Transparent" />
</StackPanel>

Wenn Sie Unterstützung für ältere Windows-Versionen (7 und 8) wünschen, schauen Sie hier nach: https://stackoverflow.com/a/27911618/9758687

2
Apfelkuacha