WPF实用指南一:在WPF窗体的边框中添加搜索框和按钮

简介: 原文:WPF实用指南一:在WPF窗体的边框中添加搜索框和按钮 在边框中加入一些元素,在应用程序的界面设计中,已经开始流行起来。
原文: WPF实用指南一:在WPF窗体的边框中添加搜索框和按钮

在边框中加入一些元素,在应用程序的界面设计中,已经开始流行起来。特别是在浏览器(Crome,IE,Firefox,Opera)中都有应用。

在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类库提供的 WindowInteropHelper类来获取。
然后从句柄中获得 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);
    }
}









目录
相关文章
WPF控件和窗体一起放大一起缩小
WPF控件和窗体一起放大一起缩小
251 0
|
C# 容器
WPF框架下,窗体的嵌套显示
WPF框架下,窗体的嵌套显示
229 0
|
C# 前端开发
wpf中的datagrid绑定操作按钮是否显示或者隐藏
如图,需要在wpf中的datagrid的操作那列有个确认按钮,然后在某些条件下确认按钮可见,某些情况下不可见的,放在mvc里直接在cshtml页面中if..else就行了。 但是在wpf里不行。。网上搜索了好久才找到解决方法,原来只是binding那个visiable属性就行了,
6901 0
|
C#
WPF 透明窗体
原文:WPF 透明窗体 窗体属性中设置:Background="Transparent" AllowsTransparency="True" WindowStyle="None"注:单独设置 Background="Transparent" 窗体默认显示为黑色。
1063 0
|
C#
wpf窗体定位
原文:wpf窗体定位 据WPF外包小编了解,通常,不需要在屏幕上明确定位窗口。而是简单地将WindowState属性设置为Normal,并忽略其他所有细节。另一方面,很少会将WindowStartupLocation属性设置为Manual,并使用Left属性和Right属性明确设置窗口的位置。
880 0
|
C# 数据安全/隐私保护
用WPF写一个登录界面,我想在输入完密码后按回车就能够验证登陆,而不需要用鼠标单击登陆按钮
原文:用WPF写一个登录界面,我想在输入完密码后按回车就能够验证登陆,而不需要用鼠标单击登陆按钮 在wpf中,将按钮的IsDefault设置为true ​​​​
1208 0
|
C# C++ Windows
WPF中不规则窗体与WindowsFormsHost控件的兼容问题完美解决方案
原文:WPF中不规则窗体与WindowsFormsHost控件的兼容问题完美解决方案          首先先得瑟一下,有关WPF中不规则窗体与WindowsFormsHost控件不兼容的问题,网上给出的解决方案不能满足所有的情况,是有特定条件的,比如  WPF中不规则窗体与WebBrowser控件的兼容问题解决办法。
1325 0
|
C#
在Winform窗体中使用WPF控件(附源码)
原文:在Winform窗体中使用WPF控件(附源码) 今天是礼拜6,下雨,没有外出,闲暇就写一篇博文讲下如何在Winform中使用WPF控件。原有是我在百度上搜索相关信息无果,遂干脆动手自己实现。 WPF控件的漂亮是Winform无法匹及的,本文主旨是在Winform工程中如何使用WPF控件。
1936 0
|
C#
WPF实现Twitter按钮效果
原文:WPF实现Twitter按钮效果 最近上网看到这个CSS3实现的Twitter按钮,感觉很漂亮,于是想用WPF来实现下. 实现这个效果,参考了CSS3 原文地址:http://www.html5tricks.
1246 0
|
C#
[原译]一步步教你制作WPF圆形玻璃按钮
原文:[原译]一步步教你制作WPF圆形玻璃按钮 图1   1.介绍 从我开始使用vista的时候,我就非常喜欢它的圆形玻璃按钮。WPF最好的一个方面就是允许自定义任何控件的样式。用了一段时间的Microsoft Expression Blend后。
1070 0