WPF 自定义窗口

本文主要展现如何建立WPF窗口样式,目前窗口未作放大和缩小功能,只作关闭。express

窗口基类建立

    /// <summary>
    /// WPF窗口基类
    /// </summary>
    /// <seealso cref="System.Windows.Window" />
    /// <seealso cref="System.IDisposable" />
    /// <seealso cref="System.ComponentModel.INotifyPropertyChanged" />
    /// <seealso cref="System.ComponentModel.INotifyPropertyChanging" />
    public class WpfWindowBase : Window,IDisposable, INotifyPropertyChanged, INotifyPropertyChanging
    {
        public WpfWindowBase()
        {
            WindowStartupLocation = WindowStartupLocation.CenterScreen;
            Loaded += WpfWindowBase_Loaded;
        }
        private void WpfWindowBase_Loaded(object sender, RoutedEventArgs e)
        {
            try
            {
                //模板
                ControlTemplate baseWindowTemplate = (ControlTemplate)Application.Current.FindResource("ControlTemplateWindows");
                if (baseWindowTemplate != null)
                {
                    //关闭按钮
                    Button closebutton = (Button)baseWindowTemplate.FindName("CloseButton", this);
                    closebutton.Click += delegate  { Close(); };
                    Border bordertop = (Border) baseWindowTemplate.FindName("TopBorder", this);
                    bordertop.MouseDown += (sen,es)=>
                    {
                        if (es.LeftButton != MouseButtonState.Pressed) { return; }
                        DragMove();
                    };
                    //设置图标
                    if (Icon != null)
                    {
                        Image image = (Image)baseWindowTemplate.FindName("Icon", this);
                        image.Source = Icon.Clone();
                    }
                    //设置标题
                    if (!string.IsNullOrEmpty(Title))
                    {
                        TextBlock title = (TextBlock)baseWindowTemplate.FindName("Title", this);
                        title.Text = Title;
                    }
                }
            }
            catch (ResourceReferenceKeyNotFoundException)
            {
           
            }
          
        }

        public event PropertyChangedEventHandler PropertyChanged;
        public event PropertyChangingEventHandler PropertyChanging;
        /// <summary>
        /// Provides access to the PropertyChanged event handler to derived classes.
        /// </summary>
        protected PropertyChangedEventHandler PropertyChangedHandler
        {
            get
            {
                return this.PropertyChanged;
            }
        }

        /// <summary>
        /// Provides access to the PropertyChanging event handler to derived classes.
        /// </summary>
        protected PropertyChangingEventHandler PropertyChangingHandler
        {
            get
            {
                return this.PropertyChanging;
            }
        }

        public virtual void Dispose()
        {

        }


        public void VerifyPropertyName(string propertyName)
        {
            Type type = this.GetType();
            if (string.IsNullOrEmpty(propertyName) || !(type.GetProperty(propertyName) == (PropertyInfo)null))
                return;
            ICustomTypeDescriptor customTypeDescriptor = this as ICustomTypeDescriptor;
            if (customTypeDescriptor == null || !customTypeDescriptor.GetProperties().Cast<PropertyDescriptor>().Any<PropertyDescriptor>((Func<PropertyDescriptor, bool>)(property => property.Name == propertyName)))
                throw new ArgumentException("Property not found", propertyName);
        }

        protected virtual void RaisePropertyChanging(string propertyName)
        {
            this.VerifyPropertyName(propertyName);
            PropertyChangingEventHandler propertyChanging = this.PropertyChanging;
            if (propertyChanging == null)
                return;
            propertyChanging((object)this, new PropertyChangingEventArgs(propertyName));
        }

        protected virtual void RaisePropertyChanged(string propertyName)
        {
            this.VerifyPropertyName(propertyName);
            PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
            if (propertyChanged == null)
                return;
            propertyChanged((object)this, new PropertyChangedEventArgs(propertyName));
        }

        protected virtual void RaisePropertyChanging<T>(System.Linq.Expressions.Expression<Func<T>> propertyExpression)
        {
            PropertyChangingEventHandler propertyChanging = this.PropertyChanging;
            if (propertyChanging == null)
                return;
            string propertyName = this.GetPropertyName<T>(propertyExpression);
            propertyChanging((object)this, new PropertyChangingEventArgs(propertyName));
        }

        protected virtual void RaisePropertyChanged<T>(System.Linq.Expressions.Expression<Func<T>> propertyExpression)
        {
            PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
            if (propertyChanged == null)
                return;
            string propertyName = this.GetPropertyName<T>(propertyExpression);
            propertyChanged((object)this, new PropertyChangedEventArgs(propertyName));
        }

        protected string GetPropertyName<T>(System.Linq.Expressions.Expression<Func<T>> propertyExpression)
        {
            if (propertyExpression == null)
                throw new ArgumentNullException(nameof(propertyExpression));
            MemberExpression body = propertyExpression.Body as MemberExpression;
            if (body == null)
                throw new ArgumentException("Invalid argument", nameof(propertyExpression));
            PropertyInfo member = body.Member as PropertyInfo;
            if (member == (PropertyInfo)null)
                throw new ArgumentException("Argument is not a property", nameof(propertyExpression));
            return member.Name;
        }
    }

窗口样式

 <Style  x:Key="CloseButton" TargetType="{x:Type Button}">
        <Setter Property="ToolTip">
            <Setter.Value>
                <ToolTip>
                    <TextBlock Text="关闭"/>
                </ToolTip>
            </Setter.Value>
        </Setter>
        <Setter Property="Width" Value="16"/>
        <Setter Property="Height" Value="16"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Image x:Name="img" Source="pack://application:,,,/TJS.Library.Base;component/Themes/Images/pic_14.png"/>
                    <ControlTemplate.Triggers>
                        <Trigger Property="UIElement.IsMouseOver" Value="true">
                            <Setter TargetName="img" Property="Image.Source" Value="pack://application:,,,/TJS.Library.Base;component/Themes/Images/pic_14_ov.png"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <ControlTemplate TargetType="{x:Type local:WpfWindowBase}" x:Key="ControlTemplateWindows" >
        <Grid  Margin="5">
            <Border Background="#FF141B25" CornerRadius="3" BorderBrush="#374141" BorderThickness="1" >
                <UIElement.Effect>
                    <DropShadowEffect ShadowDepth="0" BlurRadius="10"/>
                </UIElement.Effect>
                <Grid ClipToBounds="true" >
                    <Grid.RowDefinitions>
                        <RowDefinition Height="29"/>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <Border  BorderThickness="0,0,0,1" BorderBrush="#0F1315" x:Name="TopBorder">
                        <Border.Background>
                            <VisualBrush TileMode="Tile" ViewportUnits="Absolute">
                                <VisualBrush.Visual>
                                    <Image  Source="/Themes/Images/pg2.png"></Image>
                                </VisualBrush.Visual>
                            </VisualBrush>
                        </Border.Background>
                        <Grid>
                            <Image x:Name="Icon" Width="16" HorizontalAlignment="Left" Margin="10,0,0,0" Height="16"/>
                            <TextBlock x:Name="Title" Text="窗口" VerticalAlignment="Center" Margin="34,0,0,0"/>
                            <Button x:Name="CloseButton"  Style="{StaticResource CloseButton}" VerticalAlignment="Center"  HorizontalAlignment="Right" Margin="0,0,10,0"/>
                        </Grid>
                    </Border>
                    <ContentPresenter Grid.Row="1" />
                </Grid>
            </Border>

        </Grid>
    </ControlTemplate>
    <Style x:Key="WinStyle"  TargetType="{x:Type local:WpfWindowBase}">
        <Setter Property="Width"  Value="1366"/>
        <Setter Property="Height"  Value="768" />
        <Setter Property="WindowStyle"  Value="None"/>
        <Setter Property="AllowsTransparency"  Value="true"/>
        <Setter Property="Background"  Value="Transparent"/>
        <Setter Property="ShowInTaskbar"  Value="false"/>
        <Setter Property="Topmost"  Value="true"/>
        <Setter Property="Foreground" Value="#bdcfd1"/>
        <Setter Property="WindowState" Value="Normal"/>
        <Setter Property="Template" Value="{StaticResource ControlTemplateWindows}"></Setter>
    </Style>

具体使用

<base:WpfWindowBase x:Class="TJS.Library.AnalysisRegionModule.Views.Window1"
        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"
        xmlns:local="clr-namespace:TJS.Library.AnalysisRegionModule.Views"
        xmlns:base="clr-namespace:TJS.Library.Base;assembly=TJS.Library.Base"
        xmlns:wpf="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"
        mc:Ignorable="d" 
                    Style="{StaticResource WinStyle}"
                
        Title="Window1" Height="450" Width="800" Icon="/TJS.Library.AnalysisRegionModule;component/Images/fenxi.png">
    <Grid>

    </Grid>

</base:WpfWindowBase>

最终效果