關於WPF不規則窗體性能、大小更改


最近項目中要完成一個無框窗體的界面。主要想自己吧窗體做的更漂亮。想zune一樣。先來個圖。看下是什么樣子吧。zune界面

很漂亮吧。想想用WPF怎么寫出這個界面呢?

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

這樣當然可以做出無框的不規則窗體。但是后來發現如果我的窗體這么弄。窗體中的 Frame 無法正常加載。Frame 透明色。

經過查資料,知道了其中道理。這里就不詳細寫了。不光是這個。如果 窗體的 AllowsTransparency="True"  的話,你要是想在窗體中使用一些動畫什么的。那么 動畫的效率會非常的低。根本無法忍受。。.net 4.0 這個問題還存在。不知道4.5有沒有解決。

 

到這里我就崩潰了。難道不能寫出類似的?不會吧。

看看我的解決思路。

既然 AllowsTransparency="True" 影響性能。那么我就不用了唄。窗體會變成這樣。。

這不是我們要的效果。 窗體旁邊的邊框怎么辦? ResizeMode="NoResize" 解決問題。

但是問題又來了。 窗體怎么移動?大小如何更改。下面來說解決方案。

窗體的移動:

 這個比較簡單。 在上面自己繪制的標題欄 注冊MouseLeftButtonDown 事件。

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

 

問題解決!

下面第二問題 窗體的移動。在Winform時代,我們通過WndProc(ref Message m)處理窗體界面消息來實現,那么在WPF中是否也是如此呢?

其實在WPF中,雖說封裝比較緊密,但是對於處理界面消息這塊,和WINFORM一樣,未有所改變。下面請看具體設計:

想windows 發送消息來達到改變窗體大小的效果。具體看代碼:

View Code
<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>
View Code
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" 。這樣 如果在窗體中 使用動畫效果時候。不會影響效率。

以上代碼引用自 ryb666666博客地址:http://blog.csdn.net/ryb666666/article/details/6982510  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM