2011-07-22 101 views
26

如何爲WPF窗口創建基本的自定義窗口鑲邊,該窗口不包含關閉按鈕,仍然是可移動和可調整大小的窗口?如何在wpf中創建自定義窗口鑲邊?

+1

http://blogs.msdn.com/b/wpfsdk/archive/2008/09/08/custom-window-chrome-in-wpf .aspx – BoltClock

+0

我檢查了一下,但正在尋找更多的教程... –

+0

一個古老的,但仍然相關的問題在這裏:[用自定義視覺創建Bordless窗口](http://stackoverflow.com/questions/ 2969521 /創建-bordless - 窗口與定製視覺/ 2969652#2969652)。 –

回答

43

你設置你的窗口的WindowStyle="None",然後建立自己的窗口界面。您需要構建自己的Min/Max/Close/Drag事件處理程序,但調整大小仍然保持不變。

例如:

<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"> 
      <Button x:Name="CloseButton" DockPanel.Dock="Right" /> 
      <Button x:Name="MaxButton" DockPanel.Dock="Right" /> 
      <Button x:Name="MinButton" DockPanel.Dock="Right" /> 

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

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

</Window> 

下面是一些示例代碼隱藏公共窗口功能

/// <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"; 
    } 

} 
+0

+1 - 標題欄鼠標處理的好解決方案 –

+2

實際上,使用這個-vs-主窗口-vs-應用程序有點忙亂(就像容易出錯一樣)。亞歷克斯有更堅實的[實施](http://web.archive.org/web/20081006142447/http://blog.opennetcf.com/ayakhnin/PermaLink,guid,23a7be17-d833-4e45-b498-34ef04d98cb2.aspx)儘管它也遺漏了一些次要的功能塊。 –

+2

您可能還需要''Titlebar'' dockpanel上的'DockPanel.Dock =「Top」'。 – Aaron

35

.NET 4.5增加了一個新的類,大大簡化了這一點。

WindowChrome class讓您的Windows Presentation Foundation(WPF)的內容延伸到這通常是保留給操作系統的窗口管理器窗口的非客戶區。

您可以找到tutorial here。這個是short example usage

+0

本教程充滿了死鏈接和棄用的信息,並且簡短示例包含不再有效的程序集引用。 –

+0

謝謝你讓我知道。如果我找到更好的東西,我會發布它。 – dss539

1

我剛剛使用下面的例子.net 4.5,它工作得很好。有趣的是,它使用一個代碼作爲點擊事件的資源字典。您只需在您的app.xaml文件中引用資源字典,然後爲窗口指定樣式CustomWindowStyle。這是從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> 

而對於後面的代碼:

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!"); 
     } 
    } 
}