zoukankan      html  css  js  c++  java
  • 关于WPF不规则窗体性能和大小更改问题探讨(转)

    最近项目中要完成一个无框窗体的界面。主要想自己吧窗体做的更漂亮。想zune一样。先来个图。看下是什么样子吧。zune界面

    很漂亮吧。想想用WPF怎么写出这个界面呢?

    WindowStyle="None" AllowsTransparency="True" Background="Transparent" ??

    这样当然可以做出无框的不规则窗体。但是后来发现如果我的窗体这么弄。窗体中的 Frame 无法正常加载。Frame 透明色。

    经过查资料,知道了其中道理。这里就不详细写了。不光是这个。如果 窗体的 AllowsTransparency="True" 的话,你要是想在窗体中使用一些动画什么的。那么 动画的效率会非常的低。根本无法忍受。。.net 4.0 这个问题还存在。不知道4.5有没有解决。

    到这里我就崩溃了。难道不能写出类似的?不会吧。

    看看我的解决思路。

    既然 AllowsTransparency="True" 影响性能。那么我就不用了呗。窗体会变成这样。。

    这不是我们要的效果。 窗体旁边的边框怎么办? ResizeMode="NoResize" 解决问题。

    但是问题又来了。 窗体怎么移动?大小如何更改。下面来说解决方案。

    窗体的移动:

    这个比较简单。 在上面自己绘制的标题栏 注册MouseLeftButtonDown 事件。

    问题解决!

    下面第二问题 窗体的移动。在Winform时代,我们通过WndProc(ref Message m)处理窗体界面消息来实现,那么在WPF中是否也是如此呢?

    其实在WPF中,虽说封装比较紧密,但是对于处理界面消息这块,和WINFORM一样,未有所改变。下面请看具体设计:

    想windows 发送消息来达到改变窗体大小的效果。具体看代码:

    <Window x:Class="WpfResizeWindow.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300" WindowStyle="None" AllowsTransparency="True">
    <Grid>
    <Grid.RowDefinitions>
    <RowDefinition Height="4"/>
    <RowDefinition/>
    <RowDefinition Height="4"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
    <ColumnDefinition Width="4"/>
    <ColumnDefinition/>
    <ColumnDefinition Width="4"/>
    </Grid.ColumnDefinitions>
    <Rectangle Name="ResizeTopLeft" Fill="Black" Grid.Row="0" Grid.Column="0" MouseMove="ResizePressed" MouseDown="ResizePressed"/>
    <Rectangle Name="ResizeTop" Fill="Black" Grid.Row="0" Grid.Column="1" MouseMove="ResizePressed" MouseDown="ResizePressed"/>
    <Rectangle Name="ResizeTopRight" Fill="Black" Grid.Row="0" Grid.Column="2" MouseMove="ResizePressed" MouseDown="ResizePressed"/>
    <Rectangle Name="ResizeLeft" Fill="Black" Grid.Row="1" Grid.Column="0" MouseMove="ResizePressed" MouseDown="ResizePressed"/>
    <Rectangle Name="ResizeRight" Fill="Black" Grid.Row="1" Grid.Column="3" MouseMove="ResizePressed" MouseDown="ResizePressed"/>
    <Rectangle Name="ResizeBottomLeft" Fill="Black" Grid.Row="3" Grid.Column="0" MouseMove="ResizePressed" MouseDown="ResizePressed"/>
    <Rectangle Name="ResizeBottom" Fill="Black" Grid.Row="3" Grid.Column="1" MouseMove="ResizePressed" MouseDown="ResizePressed"/>
    <Rectangle Name="ResizeBottomRight" Fill="Black" Grid.Row="3" Grid.Column="2" MouseMove="ResizePressed" MouseDown="ResizePressed"/>
    </Grid>
    </Window>

    public partial class Window1 : Window
    {
    private const int WM_SYSCOMMAND = 0x112;
    private HwndSource _HwndSource;
    private Dictionary<ResizeDirection, Cursor> cursors = new Dictionary<ResizeDirection, Cursor>
    {
    {ResizeDirection.Top, Cursors.SizeNS},
    {ResizeDirection.Bottom, Cursors.SizeNS},
    {ResizeDirection.Left, Cursors.SizeWE},
    {ResizeDirection.Right, Cursors.SizeWE},
    {ResizeDirection.TopLeft, Cursors.SizeNWSE},
    {ResizeDirection.BottomRight, Cursors.SizeNWSE},
    {ResizeDirection.TopRight, Cursors.SizeNESW},
    {ResizeDirection.BottomLeft, Cursors.SizeNESW}
    };
    private enum ResizeDirection
    {
    Left = 1,
    Right = 2,
    Top = 3,
    TopLeft = 4,
    TopRight = 5,
    Bottom = 6,
    BottomLeft = 7,
    BottomRight = 8,
    }
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
    public Window1()
    {
    InitializeComponent();
    this.SourceInitialized += delegate(object sender, EventArgs e)
    {
    this._HwndSource = PresentationSource.FromVisual((Visual)sender) as HwndSource;
    };
    this.MouseMove += new MouseEventHandler(Window_MouseMove);
    }
    void Window_MouseMove(object sender, MouseEventArgs e)
    {
    if (Mouse.LeftButton != MouseButtonState.Pressed)
    {
    FrameworkElement element = e.OriginalSource as FrameworkElement;
    if (element != null && !element.Name.Contains("Resize"))
    this.Cursor = Cursors.Arrow;
    }
    }
    private void ResizePressed(object sender, MouseEventArgs e)
    {
    FrameworkElement element = sender as FrameworkElement;
    ResizeDirection direction = (ResizeDirection)Enum.Parse(typeof(ResizeDirection), element.Name.Replace("Resize", ""));
    this.Cursor = cursors[direction];
    if (e.LeftButton == MouseButtonState.Pressed)
    ResizeWindow(direction);
    }
    private void ResizeWindow(ResizeDirection direction)
    {
    SendMessage(_HwndSource.Handle, WM_SYSCOMMAND, (IntPtr)(61440 + direction), IntPtr.Zero);
    }
    }

    这样 无框窗体 就算做完了。在ResizeMode="NoResize" 的情况下也可以自由更改 窗体的大小。
    而且不用AllowsTransparency="True" 。这样 如果在窗体中 使用动画效果时候。不会影响效率。

    private void MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
    this.DragMove();
    }

  • 相关阅读:
    Javascript、CSS和IMG之网页执行探索
    从零开始学习Node.js例子九 设置HTTP头
    从零开始学习Node.js例子八 使用SQLite3和MongoDB
    如何做到 jQuery-free?
    jQuery的deferred对象详解
    使用openxml读取xml数据
    Drupal commerce 性能优化
    DataTable数据进行排序、检索、合并、分页、统计
    jquery实现替代iframe的功能
    9_Jvn框架之实现ORM持久层save操作(第九讲)
  • 原文地址:https://www.cnblogs.com/aoldman/p/2771196.html
Copyright © 2011-2022 走看看