• WPF自定义Window样式(1)


    目录:

    WPF自定义Window样式(1)

    WPF自定义Window样式(2)

    1. 引言

        WPF是制作界面的一大利器。最近在做一个项目,用的就是WPF。既然使用了WPF了,那么理所当然的,需要自定义窗体样式。所使用的代码是在网上查到的:原文链接

          首先上原始源码

    2. 创建项目

           创建空白项目stonemqy.CustomWindow,添加WPF项目stonemqy.CustomWindow.Main。在stonemqy.CustomWindow.Main中添加文件夹Themes,并在其中添加资源字典Generic.xaml,注意这里的Themes文件夹和Generic.xaml资源字典的名字不可更改。并在项目下依次添加类VisualStates、TransitioningContentControl和CustomWindow。

    3. VisualStates

    using System.Diagnostics;
    using System.Linq;
    using System.Windows;
    using System.Windows.Media;
    
    namespace stonemqy.CustomWindow.Main
    {
        public static class VisualStates
        {  /// <summary>
            /// This method tries to get the named VisualStateGroup for the 
            /// dependency object. The provided object's ImplementationRoot will be 
            /// looked up in this call.
            /// </summary>
            /// <param name="dependencyObject">The dependency object.</param>
            /// <param name="groupName">The visual state group's name.</param>
            /// <returns>Returns null or the VisualStateGroup object.</returns>
            public static VisualStateGroup TryGetVisualStateGroup(DependencyObject dependencyObject, string groupName)
            {
                FrameworkElement root = GetImplementationRoot(dependencyObject);
                if (root == null)
                {
                    return null;
                }
    
                return VisualStateManager.GetVisualStateGroups(root)
                    .OfType<VisualStateGroup>()
                    .Where(group => string.CompareOrdinal(groupName, group.Name) == 0)
                    .FirstOrDefault();
            }
    
            /// <summary>
            /// Gets the implementation root of the Control.
            /// </summary>
            /// <param name="dependencyObject">The DependencyObject.</param>
            /// <remarks>
            /// Implements Silverlight's corresponding internal property on Control.
            /// </remarks>
            /// <returns>Returns the implementation root or null.</returns>
            public static FrameworkElement GetImplementationRoot(DependencyObject dependencyObject)
            {
                Debug.Assert(dependencyObject != null, "DependencyObject should not be null.");
                return (1 == VisualTreeHelper.GetChildrenCount(dependencyObject)) ?
                    VisualTreeHelper.GetChild(dependencyObject, 0) as FrameworkElement :
                    null;
            }
        }
    }

    4. TransitioningContentControl

    using System;
    using System.Diagnostics.CodeAnalysis;
    using System.Linq;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Media.Animation;
    
    namespace stonemqy.CustomWindow.Main
    {
        /// <summary>
        /// Represents a control with a single piece of content and when that content 
        /// changes performs a transition animation. 
        /// </summary>
        /// <QualityBand>Experimental</QualityBand>
        /// <remarks>The API for this control will change considerably in the future.</remarks>
        [TemplateVisualState(GroupName = PresentationGroup, Name = NormalState)]
        [TemplateVisualState(GroupName = PresentationGroup, Name = DefaultTransitionState)]
        [TemplatePart(Name = PreviousContentPresentationSitePartName, Type = typeof(ContentControl))]
        [TemplatePart(Name = CurrentContentPresentationSitePartName, Type = typeof(ContentControl))]
        public class TransitioningContentControl : ContentControl
        {
            #region Visual state names
            /// <summary>
            /// The name of the group that holds the presentation states.
            /// </summary>
            private const string PresentationGroup = "PresentationStates";
    
            /// <summary>
            /// The name of the state that represents a normal situation where no
            /// transition is currently being used.
            /// </summary>
            private const string NormalState = "Normal";
    
            /// <summary>
            /// The name of the state that represents the default transition.
            /// </summary>
            public const string DefaultTransitionState = "DefaultTransition";
            #endregion Visual state names
    
            #region Template part names
            /// <summary>
            /// The name of the control that will display the previous content.
            /// </summary>
            internal const string PreviousContentPresentationSitePartName = "PreviousContentPresentationSite";
    
            /// <summary>
            /// The name of the control that will display the current content.
            /// </summary>
            internal const string CurrentContentPresentationSitePartName = "CurrentContentPresentationSite";
    
            #endregion Template part names
    
            #region TemplateParts
            /// <summary>
            /// Gets or sets the current content presentation site.
            /// </summary>
            /// <value>The current content presentation site.</value>
            private ContentPresenter CurrentContentPresentationSite { get; set; }
    
            /// <summary>
            /// Gets or sets the previous content presentation site.
            /// </summary>
            /// <value>The previous content presentation site.</value>
            private ContentPresenter PreviousContentPresentationSite { get; set; }
            #endregion TemplateParts
    
            #region public bool IsTransitioning
    
            /// <summary>
            /// Indicates whether the control allows writing IsTransitioning.
            /// </summary>
            private bool _allowIsTransitioningWrite;
    
            /// <summary>
            /// Gets a value indicating whether this instance is currently performing
            /// a transition.
            /// </summary>
            public bool IsTransitioning
            {
                get { return (bool)GetValue(IsTransitioningProperty); }
                private set
                {
                    _allowIsTransitioningWrite = true;
                    SetValue(IsTransitioningProperty, value);
                    _allowIsTransitioningWrite = false;
                }
            }
    
            /// <summary>
            /// Identifies the IsTransitioning dependency property.
            /// </summary>
            public static readonly DependencyProperty IsTransitioningProperty =
                DependencyProperty.Register(
                    "IsTransitioning",
                    typeof(bool),
                    typeof(TransitioningContentControl),
                    new PropertyMetadata(OnIsTransitioningPropertyChanged));
    
            /// <summary>
            /// IsTransitioningProperty property changed handler.
            /// </summary>
            /// <param name="d">TransitioningContentControl that changed its IsTransitioning.</param>
            /// <param name="e">Event arguments.</param>
            private static void OnIsTransitioningPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                TransitioningContentControl source = (TransitioningContentControl)d;
    
                if (!source._allowIsTransitioningWrite)
                {
                    source.IsTransitioning = (bool)e.OldValue;
                    throw new InvalidOperationException("TransitiotioningContentControl_IsTransitioningReadOnly");
                }
            }
            #endregion public bool IsTransitioning
    
            /// <summary>
            /// The storyboard that is used to transition old and new content.
            /// </summary>
            private Storyboard _currentTransition;
    
            /// <summary>
            /// Gets or sets the storyboard that is used to transition old and new content.
            /// </summary>
            private Storyboard CurrentTransition
            {
                get { return _currentTransition; }
                set
                {
                    // decouple event
                    if (_currentTransition != null)
                    {
                        _currentTransition.Completed -= OnTransitionCompleted;
                    }
    
                    _currentTransition = value;
    
                    if (_currentTransition != null)
                    {
                        _currentTransition.Completed += OnTransitionCompleted;
                    }
                }
            }
    
            #region public string Transition
            /// <summary>
            /// Gets or sets the name of the transition to use. These correspond
            /// directly to the VisualStates inside the PresentationStates group.
            /// </summary>
            public string Transition
            {
                get { return GetValue(TransitionProperty) as string; }
                set { SetValue(TransitionProperty, value); }
            }
    
            /// <summary>
            /// Identifies the Transition dependency property.
            /// </summary>
            public static readonly DependencyProperty TransitionProperty =
                DependencyProperty.Register(
                    "Transition",
                    typeof(string),
                    typeof(TransitioningContentControl),
                    new PropertyMetadata(DefaultTransitionState, OnTransitionPropertyChanged));
    
            /// <summary>
            /// TransitionProperty property changed handler.
            /// </summary>
            /// <param name="d">TransitioningContentControl that changed its Transition.</param>
            /// <param name="e">Event arguments.</param>
            private static void OnTransitionPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                TransitioningContentControl source = (TransitioningContentControl)d;
                string oldTransition = e.OldValue as string;
                string newTransition = e.NewValue as string;
    
                if (source.IsTransitioning)
                {
                    source.AbortTransition();
                }
    
                // find new transition
                Storyboard newStoryboard = source.GetStoryboard(newTransition);
    
                // unable to find the transition.
                if (newStoryboard == null)
                {
                    // could be during initialization of xaml that presentationgroups was not yet defined
                    if (VisualStates.TryGetVisualStateGroup(source, PresentationGroup) == null)
                    {
                        // will delay check
                        source.CurrentTransition = null;
                    }
                    else
                    {
                        // revert to old value
                        source.SetValue(TransitionProperty, oldTransition);
    
                        throw new ArgumentException(
                           "TransitioningContentControl_TransitionNotFound");
                    }
                }
                else
                {
                    source.CurrentTransition = newStoryboard;
                }
            }
            #endregion public string Transition
    
            #region public bool RestartTransitionOnContentChange
            /// <summary>
            /// Gets or sets a value indicating whether the current transition
            /// will be aborted when setting new content during a transition.
            /// </summary>
            public bool RestartTransitionOnContentChange
            {
                get { return (bool)GetValue(RestartTransitionOnContentChangeProperty); }
                set { SetValue(RestartTransitionOnContentChangeProperty, value); }
            }
    
            /// <summary>
            /// Identifies the RestartTransitionOnContentChange dependency property.
            /// </summary>
            public static readonly DependencyProperty RestartTransitionOnContentChangeProperty =
                DependencyProperty.Register(
                    "RestartTransitionOnContentChange",
                    typeof(bool),
                    typeof(TransitioningContentControl),
                    new PropertyMetadata(false, OnRestartTransitionOnContentChangePropertyChanged));
    
            /// <summary>
            /// RestartTransitionOnContentChangeProperty property changed handler.
            /// </summary>
            /// <param name="d">TransitioningContentControl that changed its RestartTransitionOnContentChange.</param>
            /// <param name="e">Event arguments.</param>
            private static void OnRestartTransitionOnContentChangePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                ((TransitioningContentControl)d).OnRestartTransitionOnContentChangeChanged((bool)e.OldValue, (bool)e.NewValue);
            }
    
            /// <summary>
            /// Called when the RestartTransitionOnContentChangeProperty changes.
            /// </summary>
            /// <param name="oldValue">The old value of RestartTransitionOnContentChange.</param>
            /// <param name="newValue">The new value of RestartTransitionOnContentChange.</param>
            protected virtual void OnRestartTransitionOnContentChangeChanged(bool oldValue, bool newValue)
            {
            }
            #endregion public bool RestartTransitionOnContentChange
    
            #region Events
            /// <summary>
            /// Occurs when the current transition has completed.
            /// </summary>
            public event RoutedEventHandler TransitionCompleted;
            #endregion Events
    
            /// <summary>
            /// Initializes a new instance of the <see cref="TransitioningContentControl"/> class.
            /// </summary>
            public TransitioningContentControl()
            {
                DefaultStyleKey = typeof(TransitioningContentControl);
            }
    
            /// <summary>
            /// Builds the visual tree for the TransitioningContentControl control 
            /// when a new template is applied.
            /// </summary>
            public override void OnApplyTemplate()
            {
                if (IsTransitioning)
                {
                    AbortTransition();
                }
    
                base.OnApplyTemplate();
    
                PreviousContentPresentationSite = GetTemplateChild(PreviousContentPresentationSitePartName) as ContentPresenter;
                CurrentContentPresentationSite = GetTemplateChild(CurrentContentPresentationSitePartName) as ContentPresenter;
    
                if (CurrentContentPresentationSite != null)
                {
                    CurrentContentPresentationSite.Content = Content;
                }
    
                // hookup currenttransition
                Storyboard transition = GetStoryboard(Transition);
                CurrentTransition = transition;
                if (transition == null)
                {
                    string invalidTransition = Transition;
                    // revert to default
                    Transition = DefaultTransitionState;
    
                    throw new ArgumentException(
                        "TransitioningContentControl_TransitionNotFound");
                }
    
                VisualStateManager.GoToState(this, NormalState, false);
                VisualStateManager.GoToState(this, Transition, true);
            }
    
            /// <summary>
            /// Called when the value of the <see cref="P:System.Windows.Controls.ContentControl.Content"/> property changes.
            /// </summary>
            /// <param name="oldContent">The old value of the <see cref="P:System.Windows.Controls.ContentControl.Content"/> property.</param>
            /// <param name="newContent">The new value of the <see cref="P:System.Windows.Controls.ContentControl.Content"/> property.</param>
            protected override void OnContentChanged(object oldContent, object newContent)
            {
                base.OnContentChanged(oldContent, newContent);
    
                StartTransition(oldContent, newContent);
            }
    
            /// <summary>
            /// Starts the transition.
            /// </summary>
            /// <param name="oldContent">The old content.</param>
            /// <param name="newContent">The new content.</param>
            [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "newContent", Justification = "Should be used in the future.")]
            private void StartTransition(object oldContent, object newContent)
            {
                // both presenters must be available, otherwise a transition is useless.
                if (CurrentContentPresentationSite != null && PreviousContentPresentationSite != null)
                {
                    CurrentContentPresentationSite.Content = newContent;
    
                    PreviousContentPresentationSite.Content = oldContent;
    
                    // and start a new transition
                    if (!IsTransitioning || RestartTransitionOnContentChange)
                    {
                        IsTransitioning = true;
                        VisualStateManager.GoToState(this, NormalState, false);
                        VisualStateManager.GoToState(this, Transition, true);
                    }
                }
            }
    
            /// <summary>
            /// Handles the Completed event of the transition storyboard.
            /// </summary>
            /// <param name="sender">The source of the event.</param>
            /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
            private void OnTransitionCompleted(object sender, EventArgs e)
            {
                AbortTransition();
    
                RoutedEventHandler handler = TransitionCompleted;
                if (handler != null)
                {
                    handler(this, new RoutedEventArgs());
                }
            }
    
            /// <summary>
            /// Aborts the transition and releases the previous content.
            /// </summary>
            public void AbortTransition()
            {
                // go to normal state and release our hold on the old content.
                VisualStateManager.GoToState(this, NormalState, false);
                IsTransitioning = false;
                if (PreviousContentPresentationSite != null)
                {
                    PreviousContentPresentationSite.Content = null;
                }
            }
    
            /// <summary>
            /// Attempts to find a storyboard that matches the newTransition name.
            /// </summary>
            /// <param name="newTransition">The new transition.</param>
            /// <returns>A storyboard or null, if no storyboard was found.</returns>
            private Storyboard GetStoryboard(string newTransition)
            {
                VisualStateGroup presentationGroup = VisualStates.TryGetVisualStateGroup(this, PresentationGroup);
                Storyboard newStoryboard = null;
                if (presentationGroup != null)
                {
                    newStoryboard = presentationGroup.States
                        .OfType<VisualState>()
                        .Where(state => state.Name == newTransition)
                        .Select(state => state.Storyboard)
                        .FirstOrDefault();
                }
                return newStoryboard;
            }
    
    
        }
    }

     5. CustomWindow

         此处原来有关于CustomWindow的一些注释,但是经验证,注释有误,故贴代码时将注释删除了。

    using System; 
    using System.Windows; 
    using System.Windows.Input; 
    
    namespace stonemqy.CustomWindow.Main
    {
        public class CustomWindow : Window
        {
            public CustomWindow()
            {
                DefaultStyleKey = typeof(CustomWindow);
                CommandBindings.Add(new CommandBinding(SystemCommands.CloseWindowCommand, CloseWindow));
                CommandBindings.Add(new CommandBinding(SystemCommands.MaximizeWindowCommand, MaximizeWindow, CanResizeWindow));
                CommandBindings.Add(new CommandBinding(SystemCommands.MinimizeWindowCommand, MinimizeWindow, CanMinimizeWindow));
                CommandBindings.Add(new CommandBinding(SystemCommands.RestoreWindowCommand, RestoreWindow, CanResizeWindow));
                CommandBindings.Add(new CommandBinding(SystemCommands.ShowSystemMenuCommand, ShowSystemMenu));
            }
    
            protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
            {
                base.OnMouseLeftButtonDown(e);
                if (e.ButtonState == MouseButtonState.Pressed)
                    DragMove();
            }
    
            protected override void OnContentRendered(EventArgs e)
            {
                base.OnContentRendered(e);
                if (SizeToContent == SizeToContent.WidthAndHeight)
                    InvalidateMeasure();
            }
    
            #region Window Commands
    
            private void CanResizeWindow(object sender, CanExecuteRoutedEventArgs e)
            {
                e.CanExecute = ResizeMode == ResizeMode.CanResize || ResizeMode == ResizeMode.CanResizeWithGrip;
            }
    
            private void CanMinimizeWindow(object sender, CanExecuteRoutedEventArgs e)
            {
                e.CanExecute = ResizeMode != ResizeMode.NoResize;
            }
    
            private void CloseWindow(object sender, ExecutedRoutedEventArgs e)
            {
                this.Close();
                //SystemCommands.CloseWindow(this);
            }
    
            private void MaximizeWindow(object sender, ExecutedRoutedEventArgs e)
            {
                SystemCommands.MaximizeWindow(this);
            }
    
            private void MinimizeWindow(object sender, ExecutedRoutedEventArgs e)
            {
                SystemCommands.MinimizeWindow(this);
            }
    
            private void RestoreWindow(object sender, ExecutedRoutedEventArgs e)
            {
                SystemCommands.RestoreWindow(this);
            }
    
    
            private void ShowSystemMenu(object sender, ExecutedRoutedEventArgs e)
            {
                var element = e.OriginalSource as FrameworkElement;
                if (element == null)
                    return;
    
                var point = WindowState == WindowState.Maximized ? new Point(0, element.ActualHeight)
                    : new Point(Left + BorderThickness.Left, element.ActualHeight + Top + BorderThickness.Top);
                point = element.TransformToAncestor(this).Transform(point);
                SystemCommands.ShowSystemMenu(this, point);
            }
    
            #endregion
        }
    }

    6. Generic.xaml

    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        xmlns:local="clr-namespace:stonemqy.CustomWindow.Main"
                        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity">
    
    
        <DataTemplate x:Key="RestoreWhite">
            <Grid UseLayoutRounding="True"
                  RenderTransform="1,0,0,1,.5,.5">
                <Path Data="M2,0 L8,0 L8,6 M0,3 L6,3 M0,2 L6,2 L6,8 L0,8 Z"
                      Width="8"
                      Height="8"
                      VerticalAlignment="Center"
                      HorizontalAlignment="Center"
                      Stroke="White"
                      StrokeThickness="1" />
            </Grid>
        </DataTemplate>
    
        <DataTemplate x:Key="CloseWhite">
            <Grid Margin="1,0,0,0">
    
                <Rectangle Stroke="White"
                           Height="2"
                           RenderTransformOrigin="0.5,0.5"
                           Width="11"
                           UseLayoutRounding="True">
                    <Rectangle.RenderTransform>
                        <TransformGroup>
                            <ScaleTransform />
                            <SkewTransform />
                            <RotateTransform Angle="45" />
                            <TranslateTransform />
                        </TransformGroup>
                    </Rectangle.RenderTransform>
                </Rectangle>
                <Rectangle Stroke="White"
                           Height="2"
                           RenderTransformOrigin="0.5,0.5"
                           Width="11"
                           UseLayoutRounding="True">
                    <Rectangle.RenderTransform>
                        <TransformGroup>
                            <ScaleTransform />
                            <SkewTransform />
                            <RotateTransform Angle="-45" />
                            <TranslateTransform />
                        </TransformGroup>
                    </Rectangle.RenderTransform>
                </Rectangle>
            </Grid>
        </DataTemplate>
    
        <DataTemplate x:Key="MaximizeWhite">
            <Grid>
                <Path Data="M0,1 L9,1 L9,8 L0,8 Z"
                      Width="9"
                      Height="8"
                      Margin="0,2,0,0"
                      VerticalAlignment="Center"
                      HorizontalAlignment="Center"
                      Stroke="White"
                      StrokeThickness="2" />
            </Grid>
        </DataTemplate>
    
        <DataTemplate x:Key="MinimizeWhite">
            <Grid>
                <Path Data="M0,6 L8,6 Z"
                      Width="8"
                      Height="7"
                      VerticalAlignment="Center"
                      HorizontalAlignment="Center"
                      Stroke="White"
                      StrokeThickness="2" />
            </Grid>
        </DataTemplate>
    
    
    
        <Style x:Key="TitleBarButtonFocusVisual">
            <Setter Property="Control.Template">
                <Setter.Value>
                    <ControlTemplate>
                        <Rectangle Margin="2"
                                   SnapsToDevicePixels="True"
                                   Stroke="Transparent"
                                   StrokeDashArray="1 2"
                                   StrokeThickness="1" />
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    
        <Style x:Key="TitleBarButtonStyle"
               TargetType="{x:Type Button}">
            <Setter Property="Focusable"
                    Value="False" />
            <Setter Property="Background"
                    Value="Transparent" />
            <Setter Property="BorderBrush"
                    Value="Transparent" />
            <Setter Property="BorderThickness"
                    Value="1" />
            <Setter Property="HorizontalContentAlignment"
                    Value="Center" />
            <Setter Property="VerticalContentAlignment"
                    Value="Center" />
            <Setter Property="Padding"
                    Value="1" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Button}">
                        <Grid x:Name="LayoutRoot">
                            <Rectangle x:Name="ButtonBackground"
                                       Width="28"
                                       Height="28"
                                       Fill="#FFFFFFFF"
                                       Opacity="0" />
                            <Border x:Name="ButtonBorder"
                                    BorderBrush="{TemplateBinding BorderBrush}"
                                    BorderThickness="{TemplateBinding BorderThickness}"
                                    Background="{TemplateBinding Background}"
                                    SnapsToDevicePixels="true">
                                <ContentPresenter x:Name="TitleBarButtonContentPresenter"
                                                  Focusable="False"
                                                  HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                                  Margin="{TemplateBinding Padding}"
                                                  RecognizesAccessKey="True"
                                                  SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                                  VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
                            </Border>
                        </Grid>
    
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver"
                                     Value="true">
                                <Setter Property="Opacity"
                                        Value="0.2"
                                        TargetName="ButtonBackground" />
                            </Trigger>
                            <Trigger Property="IsPressed"
                                     Value="True">
                                <Setter Property="Opacity"
                                        Value="0.4"
                                        TargetName="ButtonBackground" />
                            </Trigger>
                            <Trigger Property="IsEnabled"
                                     Value="false">
                                <Setter TargetName="TitleBarButtonContentPresenter"
                                        Property="Opacity"
                                        Value=".5" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        <!--<Style TargetType="{x:Type local:OmecWindow}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type local:OmecWindow}">
                        <Border Background="{TemplateBinding Background}"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="{TemplateBinding BorderThickness}">
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>-->
    
    
    
        <Style TargetType="{x:Type local:CustomWindow}">
            <Setter Property="Foreground"
                    Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}" />
            <Setter Property="Background"
                    Value="#FFF1F1F1" />
            <Setter Property="BorderBrush"
                    Value="#FF0874AA" />
            <Setter Property="BorderThickness"
                    Value="1" />
            <Setter Property="IsTabStop"
                    Value="False" />
            <Setter Property="ResizeMode"
                    Value="CanResizeWithGrip" />
            <Setter Property="UseLayoutRounding"
                    Value="True" />
            <Setter Property="TextOptions.TextFormattingMode"
                    Value="Display" />
            <Setter Property="WindowStyle"
                    Value="SingleBorderWindow" />
            <Setter Property="FontFamily"
                    Value="Segoe UI" />
            <Setter Property="WindowChrome.WindowChrome">
                <Setter.Value>
                    <WindowChrome CornerRadius="0"
                                  GlassFrameThickness="1"
                                  UseAeroCaptionButtons="False"
                                  NonClientFrameEdges="None" />
                </Setter.Value>
            </Setter>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type local:CustomWindow}">
    
    
                        <Border BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="{TemplateBinding BorderThickness}"
                                x:Name="WindowBorder">
                            <Grid x:Name="LayoutRoot"
                                  Background="{TemplateBinding Background}">
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="Auto" />
                                    <RowDefinition Height="*" />
                                </Grid.RowDefinitions>
    
                                <Grid x:Name="PART_WindowTitleGrid"
                                      Grid.Row="0"
                                      Height="26.4"
                                      Background="{TemplateBinding BorderBrush}">
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="*" />
                                        <ColumnDefinition Width="Auto" />
                                    </Grid.ColumnDefinitions>
                                    <StackPanel Orientation="Horizontal">
                                        <!--<Image Source="{TemplateBinding Icon}"
                                               Margin="7,0,5,0"
                                               VerticalAlignment="Center"
                                              />-->
                                        <Button VerticalAlignment="Center"
                                                Margin="7,0,5,0"
                                                Content="{TemplateBinding Icon}"
                                                Height="{x:Static SystemParameters.SmallIconHeight}"
                                                Width="{x:Static SystemParameters.SmallIconWidth}"
                                                WindowChrome.IsHitTestVisibleInChrome="True"
                                                IsTabStop="False">
                                            <Button.Template>
                                                <ControlTemplate TargetType="{x:Type Button}">
                                                    <Image Source="{TemplateBinding Content}" />
                                                </ControlTemplate>
                                            </Button.Template>
                                            <i:Interaction.Triggers>
                                                <i:EventTrigger EventName="Click">
                                                    <i:InvokeCommandAction Command="{x:Static SystemCommands.ShowSystemMenuCommand}" />
                                                </i:EventTrigger>
                                                <i:EventTrigger EventName="MouseDoubleClick">
                                                    <i:InvokeCommandAction Command="{x:Static SystemCommands.CloseWindowCommand}" />
                                                </i:EventTrigger>
                                            </i:Interaction.Triggers>
                                        </Button>
                                        <ContentControl IsTabStop="False"
                                                        Foreground="White"
                                                        HorizontalAlignment="Center"
                                                        VerticalAlignment="Center"
                                                        FontSize="{DynamicResource {x:Static SystemFonts.CaptionFontSize}}"
                                                        Content="{TemplateBinding Title}" />
                                    </StackPanel>
                                    <StackPanel x:Name="WindowCommandButtonsStackPanel"
                                                Grid.Column="1"
                                                HorizontalAlignment="Right"
                                                VerticalAlignment="Top"
                                                Background="Transparent"
                                                Orientation="Horizontal"
                                                WindowChrome.IsHitTestVisibleInChrome="True">
                                        <Button x:Name="Minimize"
                                                ToolTip="Minimize"
                                                WindowChrome.IsHitTestVisibleInChrome="True"
                                                Command="{Binding Source={x:Static SystemCommands.MinimizeWindowCommand}}"
                                                ContentTemplate="{StaticResource MinimizeWhite}"
                                                Style="{StaticResource TitleBarButtonStyle}"
                                                IsTabStop="False" />
                                        <Grid Margin="1,0,1,0">
                                            <Button x:Name="Restore"
                                                    ToolTip="Restore"
                                                    WindowChrome.IsHitTestVisibleInChrome="True"
                                                    Command="{Binding Source={x:Static SystemCommands.RestoreWindowCommand}}"
                                                    ContentTemplate="{StaticResource RestoreWhite}"
                                                    Style="{StaticResource TitleBarButtonStyle}"
                                                    Visibility="Collapsed"
                                                    IsTabStop="False" />
                                            <Button x:Name="Maximize"
                                                    ToolTip="Maximize"
                                                    WindowChrome.IsHitTestVisibleInChrome="True"
                                                    Command="{Binding Source={x:Static SystemCommands.MaximizeWindowCommand}}"
                                                    ContentTemplate="{StaticResource MaximizeWhite}"
                                                    Style="{StaticResource TitleBarButtonStyle}"
                                                    IsTabStop="False" />
                                        </Grid>
                                        <Button x:Name="Close"
                                                ToolTip="Close"
                                                WindowChrome.IsHitTestVisibleInChrome="True"
                                                Command="{Binding Source={x:Static SystemCommands.CloseWindowCommand}}"
                                                ContentTemplate="{StaticResource CloseWhite}"
                                                Style="{StaticResource TitleBarButtonStyle}"
                                                IsTabStop="False" />
                                    </StackPanel>
                                </Grid>
                                <AdornerDecorator Grid.Row="1" KeyboardNavigation.IsTabStop="False">
                                    <!--<ContentPresenter x:Name="MainContentPresenter"
                                                      KeyboardNavigation.TabNavigation="Cycle" />-->
                                    <local:TransitioningContentControl Content="{TemplateBinding Content}"
                                                                       x:Name="MainContentPresenter"
                                                                    
                                                                       KeyboardNavigation.TabNavigation="Cycle" />
                                </AdornerDecorator>
                                <ResizeGrip x:Name="ResizeGrip"
                                            HorizontalAlignment="Right"
                                            VerticalAlignment="Bottom"
                                            Grid.Row="1"
                                            IsTabStop="False"
                                            Visibility="Hidden"
                                            WindowChrome.ResizeGripDirection="BottomRight" />
                            </Grid>
                        </Border>
    
    
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsActive"
                                     Value="False">
                                <Setter Property="BorderBrush"
                                        Value="#FF6F7785" />
                            </Trigger>
                            <Trigger Property="WindowState"
                                     Value="Maximized">
                                <Setter TargetName="Maximize"
                                        Property="Visibility"
                                        Value="Collapsed" />
                                <Setter TargetName="Restore"
                                        Property="Visibility"
                                        Value="Visible" />
                                <Setter TargetName="LayoutRoot"
                                        Property="Margin"
                                        Value="7" />
                            </Trigger>
                            <Trigger Property="WindowState"
                                     Value="Normal">
                                <Setter TargetName="Maximize"
                                        Property="Visibility"
                                        Value="Visible" />
                                <Setter TargetName="Restore"
                                        Property="Visibility"
                                        Value="Collapsed" />
                            </Trigger>
                            <Trigger Property="ResizeMode"
                                     Value="NoResize">
                                <Setter TargetName="Minimize"
                                        Property="Visibility"
                                        Value="Collapsed" />
                                <Setter TargetName="Maximize"
                                        Property="Visibility"
                                        Value="Collapsed" />
                                <Setter TargetName="Restore"
                                        Property="Visibility"
                                        Value="Collapsed" />
                            </Trigger>
    
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="ResizeMode"
                                               Value="CanResizeWithGrip" />
                                    <Condition Property="WindowState"
                                               Value="Normal" />
                                </MultiTrigger.Conditions>
                                <Setter TargetName="ResizeGrip"
                                        Property="Visibility"
                                        Value="Visible" />
                            </MultiTrigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
    
        </Style>
    
    
    
        <Style TargetType="local:TransitioningContentControl">
            <Setter Property="IsTabStop"
                    Value="False" />
            <Setter Property="HorizontalContentAlignment"
                    Value="Stretch" />
            <Setter Property="VerticalContentAlignment"
                    Value="Stretch" />
            <Setter Property="Transition"
                    Value="DefaultTransition" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="local:TransitioningContentControl">
                        <Border Background="{TemplateBinding Background}"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="{TemplateBinding BorderThickness}"
                                CornerRadius="2">
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="PresentationStates">
                                    <VisualState x:Name="DefaultTransition">
                                        <Storyboard>
                                            <!--<DoubleAnimationUsingKeyFrames 
                                                BeginTime="00:00:00" 
                                                Storyboard.TargetName="CurrentContentPresentationSite"
                                                Storyboard.TargetProperty="(UIElement.Opacity)">
                                                <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
                                                <SplineDoubleKeyFrame KeyTime="00:00:00.300" Value="1"/>
                                            </DoubleAnimationUsingKeyFrames>
                                            <DoubleAnimationUsingKeyFrames
                                                BeginTime="00:00:00" 
                                                Storyboard.TargetName="PreviousContentPresentationSite" 
                                                Storyboard.TargetProperty="(UIElement.Opacity)">
                                                <SplineDoubleKeyFrame KeyTime="00:00:00" Value="1"/>
                                                <SplineDoubleKeyFrame KeyTime="00:00:00.300" Value="0"/>
                                            </DoubleAnimationUsingKeyFrames>-->
                                            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                                                                           Storyboard.TargetName="CurrentContentPresentationSite"
                                                                           Storyboard.TargetProperty="(UIElement.Opacity)">
                                                <SplineDoubleKeyFrame KeyTime="00:00:00"
                                                                      Value="0" />
                                                <SplineDoubleKeyFrame KeyTime="00:00:00.400"
                                                                      Value="1" />
                                            </DoubleAnimationUsingKeyFrames>
    
                                            <DoubleAnimation BeginTime="00:00:00"
                                                             Duration="00:00:00.500"
                                                             Storyboard.TargetName="CurrentContentPresentationSite"
                                                             Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)"
                                                             From="50"
                                                             To="0">
                                                <DoubleAnimation.EasingFunction>
                                                    <CubicEase EasingMode="EaseOut" />
                                                </DoubleAnimation.EasingFunction>
                                            </DoubleAnimation>
    
                                            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                                                                           Storyboard.TargetName="PreviousContentPresentationSite"
                                                                           Storyboard.TargetProperty="(UIElement.Opacity)">
                                                <SplineDoubleKeyFrame KeyTime="00:00:00"
                                                                      Value="1" />
                                                <SplineDoubleKeyFrame KeyTime="00:00:00.100"
                                                                      Value="0" />
                                            </DoubleAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Normal">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames BeginTime="00:00:00"
                                                                           Storyboard.TargetName="PreviousContentPresentationSite"
                                                                           Storyboard.TargetProperty="(UIElement.Visibility)">
                                                <DiscreteObjectKeyFrame KeyTime="00:00:00">
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <Visibility>Collapsed</Visibility>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
    
                                    <VisualState x:Name="UpTransition">
                                        <Storyboard>
                                            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                                                                           Storyboard.TargetName="CurrentContentPresentationSite"
                                                                           Storyboard.TargetProperty="(UIElement.Opacity)">
                                                <SplineDoubleKeyFrame KeyTime="00:00:00"
                                                                      Value="0" />
                                                <SplineDoubleKeyFrame KeyTime="00:00:00.300"
                                                                      Value="1" />
                                            </DoubleAnimationUsingKeyFrames>
    
                                            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                                                                           Storyboard.TargetName="CurrentContentPresentationSite"
                                                                           Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)">
                                                <SplineDoubleKeyFrame KeyTime="00:00:00"
                                                                      Value="30" />
                                                <SplineDoubleKeyFrame KeyTime="00:00:00.300"
                                                                      Value="0" />
                                            </DoubleAnimationUsingKeyFrames>
    
                                            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                                                                           Storyboard.TargetName="PreviousContentPresentationSite"
                                                                           Storyboard.TargetProperty="(UIElement.Opacity)">
                                                <SplineDoubleKeyFrame KeyTime="00:00:00"
                                                                      Value="1" />
                                                <SplineDoubleKeyFrame KeyTime="00:00:00.300"
                                                                      Value="0" />
                                            </DoubleAnimationUsingKeyFrames>
    
                                            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                                                                           Storyboard.TargetName="PreviousContentPresentationSite"
                                                                           Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)">
                                                <SplineDoubleKeyFrame KeyTime="00:00:00"
                                                                      Value="0" />
                                                <SplineDoubleKeyFrame KeyTime="00:00:00.300"
                                                                      Value="-30" />
                                            </DoubleAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
    
                                    <VisualState x:Name="DownTransition">
                                        <Storyboard>
                                            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                                                                           Storyboard.TargetName="CurrentContentPresentationSite"
                                                                           Storyboard.TargetProperty="(UIElement.Opacity)">
                                                <SplineDoubleKeyFrame KeyTime="00:00:00"
                                                                      Value="0" />
                                                <SplineDoubleKeyFrame KeyTime="00:00:00.300"
                                                                      Value="1" />
                                            </DoubleAnimationUsingKeyFrames>
    
                                            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                                                                           Storyboard.TargetName="CurrentContentPresentationSite"
                                                                           Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)">
                                                <SplineDoubleKeyFrame KeyTime="00:00:00"
                                                                      Value="-40" />
                                                <SplineDoubleKeyFrame KeyTime="00:00:00.300"
                                                                      Value="0" />
                                            </DoubleAnimationUsingKeyFrames>
    
                                            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                                                                           Storyboard.TargetName="PreviousContentPresentationSite"
                                                                           Storyboard.TargetProperty="(UIElement.Opacity)">
                                                <SplineDoubleKeyFrame KeyTime="00:00:00"
                                                                      Value="1" />
                                                <SplineDoubleKeyFrame KeyTime="00:00:00.300"
                                                                      Value="0" />
                                            </DoubleAnimationUsingKeyFrames>
    
                                            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                                                                           Storyboard.TargetName="PreviousContentPresentationSite"
                                                                           Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)">
                                                <SplineDoubleKeyFrame KeyTime="00:00:00"
                                                                      Value="0" />
                                                <SplineDoubleKeyFrame KeyTime="00:00:00.300"
                                                                      Value="40" />
                                            </DoubleAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
    
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
    
                            <Grid>
                                <ContentPresenter x:Name="PreviousContentPresentationSite"
                                                  Content="{x:Null}"
                                                  ContentTemplate="{TemplateBinding ContentTemplate}"
                                                  HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                                  VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
                                    <ContentPresenter.RenderTransform>
                                        <TransformGroup>
                                            <ScaleTransform />
                                            <SkewTransform />
                                            <RotateTransform />
                                            <TranslateTransform />
                                        </TransformGroup>
                                    </ContentPresenter.RenderTransform>
                                </ContentPresenter>
    
                                <ContentPresenter x:Name="CurrentContentPresentationSite"
                                                  Content="{x:Null}"
                                                  ContentTemplate="{TemplateBinding ContentTemplate}"
                                                  HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                                  VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
                                    <ContentPresenter.RenderTransform>
                                        <TransformGroup>
                                            <ScaleTransform />
                                            <SkewTransform />
                                            <RotateTransform />
                                            <TranslateTransform />
                                        </TransformGroup>
                                    </ContentPresenter.RenderTransform>
                                </ContentPresenter>
                            </Grid>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ResourceDictionary>

    7. MainWindow.xaml

    <local:CustomWindow x:Class="stonemqy.CustomWindow.Main.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:stonemqy.CustomWindow.Main"
            Title="MainWindow" Height="350" Width="525">
        <Grid>
            
        </Grid>
    </local:CustomWindow>

    8. MainWindow.cs

    namespace stonemqy.CustomWindow.Main
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : CustomWindow
        {
            public MainWindow()
            {
                InitializeComponent();
            }
        }
    }

    9. 运行效果

    10. 项目代码

    源码

    学到的就要教人
  • 相关阅读:
    Django基础
    XSS BOT编写
    Weblogic ssrf+Redis Getshell学习
    CORS与JSONP配置不当所导致的信息泄露
    VulnHub FristLeaks 1.3
    攻防世界--REVERSE新手练习区writeup
    2019第三届强网杯线下3道RW
    SCTF2019--WEB 2题复现
    文件上传--利用.htaccess绕过黑名单
    CEF 与 QML 对比
  • 原文地址:https://www.cnblogs.com/stonemqy/p/8266790.html
Copyright © 2020-2023  润新知