【问题标题】:Get Window Object in WPF ResourceDictionary based window在基于 WPF ResourceDictionary 的窗口中获取窗口对象
【发布时间】:2012-07-25 07:21:38
【问题描述】:

在 VS2008 中,我在解决方案中添加了一个资源字典模板,我将此模板命名为“MyWinStyle.xaml”。 以下是我的窗口中使用的样式: ……

<!--Window Template-->
<ControlTemplate x:Key="MyWindowTemplate" TargetType="{x:Type Window}">
.....
</ControlTemplate>

<!--Window Style-->
<Style x:Key="MacWindowStyle" TargetType="Window">
    ....
    <Setter Property="Template" Value="{StaticResource MyWindowTemplate}" />
</Style>

</ResourceDictionary>

这是我的XMAL代码,当我想添加使ownerdraw窗口可调整大小的函数时,我遇到了一个问题,就是在它的构造函数中无法获取Window对象。(基于这篇文章,我想让我的窗口调整大小:http://blog.kirupa.com/?p=256) 以下是我的代码:

public partial class MyStyledWindow : ResourceDictionary
{
    private const int WM_SYSCOMMAND = 0x112;
    private HwndSource hwndSource;
    IntPtr retInt = IntPtr.Zero;

    public MacStyledWindow()
    {
        InitializeComponent();
        /**
         **Would anyone suggest on this? I can't get window object
         **/
Window.SourceInitialized += new EventHandler(MainWindow_SourceInitialized);
    }

    private void MainWindow_SourceInitialized(object sender, EventArgs e)
    {
        hwndSource = PresentationSource.FromVisual((Visual)sender) as HwndSource;
        hwndSource.AddHook(new HwndSourceHook(WndProc));
    }

    private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
    {
        Debug.WriteLine("WndProc messages: " + msg.ToString());
        //
        // Check incoming window system messages
        //
        if (msg == WM_SYSCOMMAND)
        {
            Debug.WriteLine("WndProc messages: " + msg.ToString());
        }

        return IntPtr.Zero;
    }

    public 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);

    private void ResizeWindow(ResizeDirection direction)
    {
        SendMessage(hwndSource.Handle, WM_SYSCOMMAND, (IntPtr)(61440 + direction), IntPtr.Zero);
    }

    private void ResetCursor(object sender, MouseEventArgs e)
    {
        var window = (Window)((FrameworkElement)sender).TemplatedParent;
        if (Mouse.LeftButton != MouseButtonState.Pressed)
        {
            window.Cursor = Cursors.Arrow;
        }
    }

    private void Resize(object sender, MouseButtonEventArgs e)
    {
        Rectangle clickedRectangle = sender as Rectangle;
        var window = (Window)((FrameworkElement)sender).TemplatedParent;
        switch (clickedRectangle.Name)
        {
            case "top":
                window.Cursor = Cursors.SizeNS;
                ResizeWindow(ResizeDirection.Top);
                break;
            case "bottom":
                window.Cursor = Cursors.SizeNS;
                ResizeWindow(ResizeDirection.Bottom);
                break;
            case "left":
                window.Cursor = Cursors.SizeWE;
                ResizeWindow(ResizeDirection.Left);
                break;
            case "right":
                window.Cursor = Cursors.SizeWE;
                ResizeWindow(ResizeDirection.Right);
                break;
            case "topLeft":
                window.Cursor = Cursors.SizeNWSE;
                ResizeWindow(ResizeDirection.TopLeft);
                break;
            case "topRight":
                window.Cursor = Cursors.SizeNESW;
                ResizeWindow(ResizeDirection.TopRight);
                break;
            case "bottomLeft":
                window.Cursor = Cursors.SizeNESW;
                ResizeWindow(ResizeDirection.BottomLeft);
                break;
            case "bottomRight":
                window.Cursor = Cursors.SizeNWSE;
                ResizeWindow(ResizeDirection.BottomRight);
                break;
            default:
                break;
        }
    }

    private void DisplayResizeCursor(object sender, MouseEventArgs e)
    {
        Rectangle clickedRectangle = sender as Rectangle;
        var window = (Window)((FrameworkElement)sender).TemplatedParent;
        switch (clickedRectangle.Name)
        {
            case "top":
                window.Cursor = Cursors.SizeNS;
                break;
            case "bottom":
                window.Cursor = Cursors.SizeNS;
                break;
            case "left":
                window.Cursor = Cursors.SizeWE;
                break;
            case "right":
                window.Cursor = Cursors.SizeWE;
                break;
            case "topLeft":
                window.Cursor = Cursors.SizeNWSE;
                break;
            case "topRight":
                window.Cursor = Cursors.SizeNESW;
                break;
            case "bottomLeft":
                window.Cursor = Cursors.SizeNESW;
                break;
            case "bottomRight":
                window.Cursor = Cursors.SizeNWSE;
                break;
            default:
                break;
        }
    }

    private void Drag(object sender, MouseButtonEventArgs e)
    {
        var window = (Window)((FrameworkElement)sender).TemplatedParent;
        window.DragMove();
    }
}
}

【问题讨论】:

    标签: c# wpf resize window ownerdrawn


    【解决方案1】:

    为什么要使用 ResourceDictionary 作为窗口的基类?将您的基类更改为 Window,您将能够订阅 SourceInitialized 事件。那就是:

        public partial class MyStyledWindow : Window
        {
        //other code
    

    【讨论】:

    • 我知道,但我所有的窗口(大约 30 个)都将使用相同的样式,按你说的做可能会让我发疯。
    • 您的所有窗口只有一个类 (MyStyledWindow),然后使用 MyStyledWindow 而不是普通的 Window 类。在您的控件模板和样式声明中,使用TargetType="{x:Type MyStyledWindow}" 将它们应用到您的 MyStyledWindow。在此处查看自定义窗口的实现方式:wpfwindow.codeplex.com。希望这会有所帮助
    猜你喜欢
    • 2013-06-17
    • 1970-01-01
    • 1970-01-01
    • 2017-09-06
    • 2021-08-06
    • 2018-11-10
    • 1970-01-01
    • 2019-11-27
    • 2012-05-04
    相关资源
    最近更新 更多