天天看點

WPF實用指南一:在WPF窗體的邊框中添加搜尋框和按鈕

原文: WPF實用指南一:在WPF窗體的邊框中添加搜尋框和按鈕

在邊框中加入一些元素,在應用程式的界面設計中,已經開始流行起來。特别是在浏覽器(Crome,IE,Firefox,Opera)中都有應用。

在WPF中,如何實作這種效果呢?這正是我們今天需要探讨的問題。先看看實作效果

WPF實用指南一:在WPF窗體的邊框中添加搜尋框和按鈕
圖一:實作之前的效果                                                                                                                                        
WPF實用指南一:在WPF窗體的邊框中添加搜尋框和按鈕

圖二:實作之後的效果

這樣的效果依賴于作業系統Aero風格的支援,也就是說在Windows Vista,Windows 7 或者更高版本中可以獲得此中效果。如果要在Windows XP中實作,那麼您就需要另外想辦法了。

好了。我們來看看是怎麼實作的吧。

首先:在MainWindow窗體的xaml代碼中加入以下代碼,這一步沒有什麼特别的,和平常做的一樣。

<Grid.RowDefinitions>
            <RowDefinition Height="30" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <StackPanel Orientation="Horizontal"  HorizontalAlignment="Right" VerticalAlignment="Center">
 
            <TextBox Width="150"  VerticalAlignment="Center" Text="輸入關鍵詞" /> 
            <Button Content="查找" VerticalAlignment="Center" Margin="5,0,5,0" />
        </StackPanel>
 
        <Grid Background="White" Grid.Row="1">
            <Label Content="Hello World"></Label>
        </Grid>           

然後:為窗體設定背景。這一步比較重要,要實作上面圖檔的效果,需要将其設定為Transparent

Background="Transparent"           

好了,到此xaml的編輯已經結束了,接下來看看背景代碼是如何實作的。

如果你建立的是WPF的應用程式,隻需要添加System.Drawing引用即可。

using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Interop;
using System.Runtime.InteropServices;           

要實作上述效果,需要使用一個Win32函數

DwmExtendFrameIntoClientArea

這個函數需要個

MARGINS

的結構體。代碼定義如下

[StructLayout(LayoutKind.Sequential)]
public struct MARGINS
{
  public int cxLeftWidth;
  public int cxRightWidth;
  public int cxTopHeight;
  public int cxBottomHeight;
}

[DllImport("dwmapi.dll")]
public static extern int DwmExtendFrameIntoClientArea(
  IntPtr hWnd, ref MARGINS pMarInset);           

Windows

API使用句柄控制着窗體,是以在窗體的Load事件中,第一步我們需要擷取窗體的句柄,使用.NET類庫提供的

WindowInteropHelp

er類來擷取。

然後從句柄中獲得

HwndSource

,它用來宿主WPF的内容。接下來建立MARGINS結構體執行個體用來存儲相關設定。最後調用API。看看代碼實作:

void OnLoaded(object sender, RoutedEventArgs e)
        {
            IntPtr windowHandle = new WindowInteropHelper(this).Handle; 
            HwndSource window = HwndSource.FromHwnd(windowHandle); 
            window.CompositionTarget.BackgroundColor = Colors.Transparent; 
            MARGINS margins = new MARGINS();
            margins.cxTopHeight = 30; 
            margins = AdjustForDPISettings(margins, windowHandle); 
            int result = DwmExtendFrameIntoClientArea(windowHandle, ref margins);
        }           
private MARGINS AdjustForDPISettings(MARGINS input, IntPtr hWnd)
        {
            MARGINS adjusted = new MARGINS();              
            var graphics = System.Drawing.Graphics.FromHwnd(hWnd);
            float dpiRatioX = graphics.DpiX / 96;
            float dpiRatioY = graphics.DpiY / 96;
            adjusted.cxLeftWidth = (int)(input.cxLeftWidth * dpiRatioX);
            adjusted.cxRightWidth = (int)(input.cxRightWidth * dpiRatioX);
            adjusted.cxTopHeight = (int)(input.cxTopHeight * dpiRatioY);
            adjusted.cxBottomHeight = (int)(input.cxBottomHeight * dpiRatioY);
            return adjusted;
        }           

到此,整個效果就都實作了。完整代碼如下:

using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Interop;
using System.Runtime.InteropServices;

namespace WpfTutorial
{
    /// <summary>
    /// MainWindow.xaml 的互動邏輯
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.Loaded += OnLoaded;
        }
        void OnLoaded(object sender, RoutedEventArgs e)
        {
            IntPtr windowHandle = new WindowInteropHelper(this).Handle; 
            HwndSource window = HwndSource.FromHwnd(windowHandle); 
            window.CompositionTarget.BackgroundColor = Colors.Transparent; 
            MARGINS margins = new MARGINS();
            margins.cxTopHeight = 30; 
            margins = AdjustForDPISettings(margins, windowHandle); 
            int result = DwmExtendFrameIntoClientArea(windowHandle, ref margins);
        }

        private MARGINS AdjustForDPISettings(MARGINS input, IntPtr hWnd)
        {
            MARGINS adjusted = new MARGINS();              
            var graphics = System.Drawing.Graphics.FromHwnd(hWnd);
            float dpiRatioX = graphics.DpiX / 96;
            float dpiRatioY = graphics.DpiY / 96;
            adjusted.cxLeftWidth = (int)(input.cxLeftWidth * dpiRatioX);
            adjusted.cxRightWidth = (int)(input.cxRightWidth * dpiRatioX);
            adjusted.cxTopHeight = (int)(input.cxTopHeight * dpiRatioY);
            adjusted.cxBottomHeight = (int)(input.cxBottomHeight * dpiRatioY);
            return adjusted;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct MARGINS
        {
            public int cxLeftWidth;
            public int cxRightWidth;
            public int cxTopHeight;
            public int cxBottomHeight;
        }

        [DllImport("dwmapi.dll")]
        public static extern int DwmExtendFrameIntoClientArea(
          IntPtr hWnd, ref MARGINS pMarInset);
    }
}
           

繼續閱讀