WPF中的MDI行为?

时间:2012-09-10 19:49:33

标签: wpf mdi

我正在编写一个工业过程控制应用程序,使用.Net在PC上运行。该程序监控工厂车间团队正在组装的各个部件的进度。可以有任意数量的部件 - 1,2,3,4,5等,并且在应用程序的旧VB6版本中,每个部件都有自己的窗口,操作员喜欢将它们排列在屏幕上。

我所描述的是经典的MDI接口,但WPF不支持MDI。 SO上的其他主题建议在Codeplex上使用wpfmdi项目,但是自去年2月(http://wpfmdi.codeplex.com)和avalondocks之后被列为“废弃”项目,但是那些看起来不像是可以任意拖动和移动的对接区块。

我不知道该怎么办。我不想使用WinForms,因为WPF / XAML提供更酷的视觉效果和更简单的样式,因为微软似乎放弃了WinForms。目前该产品的VB6版本已有12年历史,我想为新产品规划类似的生命周期。

提前致谢!

2 个答案:

答案 0 :(得分:0)

我认为您应该考虑使用付费的第三方组件来支持MDI。几乎所有标准供应商,DevExpress,Component One,Infragisitcs,Telerik都提供MDI解决方案。

就个人而言,我认为MDI仍然是一个完全有效的应用程序UI结构!

答案 1 :(得分:0)

我在另一个讨论论坛上找到了答案(我无法记住哪一个或我给予他们信任)。事实证明这比我想象的要容易。如果您挂钩WM_MOVING消息(我在下面加载窗口时),您可以在移动窗口之前拦截移动并约束窗口的位置。

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    WindowInteropHelper helper = new WindowInteropHelper(this);
    HwndSource.FromHwnd(helper.Handle).AddHook(HwndMessageHook);

    InitialWindowLocation = new Point(this.Left, this.Top);
}

// Grab the Win32 WM_MOVING message so we can intercept a move BEFORE 
// it happens and constrain the child window's location.

private IntPtr HwndMessageHook(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam, ref bool bHandled)
{
    switch (msg)
    {
        //   might also want to handle case WM_SIZING:
        case WM_MOVING:
            {
                WIN32Rectangle rectangle = (WIN32Rectangle)Marshal.PtrToStructure(lParam, typeof(WIN32Rectangle));

                if (rectangle.Top < 50)
                {
                    rectangle.Top = 50;
                    rectangle.Bottom = 50 + (int)this.Height;
                    bHandled = true;
                }

                if (rectangle.Left < 10)
                {
                    rectangle.Left = 10;
                    rectangle.Right = 10 + (int)this.Width;
                    bHandled = true;
                }

                if (rectangle.Bottom >800)
                {
                    rectangle.Bottom = 800;
                    rectangle.Top = 800 - (int)this.Height;
                    bHandled = true;
                }

                // do anything to handle Right case?
                if (bHandled)
                {
                    Marshal.StructureToPtr(rectangle, lParam, true);
                }
            }
            break;
    }
    return IntPtr.Zero;
}

XAML标题如下所示:

<Window x:Class="Mockup_9.Entity11"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:Mockup_9"
        ShowInTaskbar="False"
        Background="LightGoldenrodYellow"
        Loaded="Window_Loaded"
        Title="Mockup_part -" Height="540" Width="380" ResizeMode="NoResize"
        Icon="/Mockup_9;component/Images/refresh-icon1.jpg">

。 。 。等