本文主要展現如何建立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>