彩票走势图

如何使用WPF实现MDI窗口

转帖|其它|编辑:郝浩|2011-05-26 14:44:48.000|阅读 3665 次

概述:WPF本身并没有提供WPF实现,但是有个简单的方法可以实现MDI方法。

# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>

  WPF本身并没有提供MDI实现,但是有个简单的方法可以实现MDI方法。

  第一步:添加引用API方法

using System;    
using System.Runtime.InteropServices;    
   
namespace WPFMdi {    
     public class Win32Native {    
         [DllImport( "user32.dll", EntryPoint = "SetParent")]    
         public extern static IntPtr SetParent(IntPtr childPtr, IntPtr parentPtr);    
     }    
}    

  第二步:子父窗口设置

using System.Windows;    
using System.Windows.Interop;    
   
namespace WPFMdi {    
     ///  <summary>    
     /// MainWindow.xaml 的交互逻辑    
     ///  </summary>    
     public partial class MainWindow : Window {    
         public MainWindow() {    
             InitializeComponent();    
         }    
   
         private void button1_Click(object sender, RoutedEventArgs e) {    
             ChildWindow win = new ChildWindow();    
             win.Show();    
   
             //创建MDI窗体    
             WindowInteropHelper parentHelper = new WindowInteropHelper(this);    
             WindowInteropHelper childHelper = new WindowInteropHelper(win);    
             Win32Native.SetParent(childHelper.Handle, parentHelper.Handle);    
         }    
     }    
}    

 

  虽然实现了MDI窗口,但是还有一些问题:先设置好主窗口背景图片(为了能演示出效果),然后创建一个子窗口,当移动子窗口时,子窗口的边缘产生了花屏效果。

  分析了原因,应该是当窗口移动时,渲染产生了问题。所以我迫切希望在子窗口的LocationChanged事件中重绘,WPF中没有Invalidate方法,试了很多方法也没有成功。请教高手如何解决这个问题,或者如何重绘子窗口,使其边缘不产生花屏效果。

  我的临时解决方案:我发现当窗口大小发生变化后,窗口会自动重绘,边缘的花屏也就没了,正常了。于是我在LocationChanged事件中更改窗口大小

using System;    
using System.Windows;    
   
namespace WPFMdi {    
     ///  <summary>    
     /// ChildWindow.xaml 的交互逻辑    
     ///  </summary>    
     public partial class ChildWindow : Window {    
         public ChildWindow() {    
             InitializeComponent();    
         }   
  
         #region Window重绘处理    
         int count = 0;    
         private void Window_LocationChanged(object sender, EventArgs e) {    
             if (count  < 10) {    
                 this.Width += 0.101;    
             } else if (count  < 20) {    
                 this.Width -= 0.102;    
             }       
             count = ++count % 20;    
         }   
         #endregion    
     }    
}    

  微软论坛对于该问题的回答:

  很遗憾的是,WPF本身没有实现MDI,所以你会想到用Host的方式,将一个窗体的句柄设置为另一窗体的子窗体 (调用 SetParent API)

  这一点就会引起问题,WPF不同于一般的Win32程序,本身内容是没有句柄的,因为它通过DX去实现绘制,所以消息循环就不同于Win32的窗体了,不能有一个消息队列来对应每一个组件,来各自处理不同的消息,来处理每一次的重绘消息。何况,WPF使用DX后,为了提高性能,缓存了大量的UI信息,使并不是每次窗体区域被遮住或者改变都要进行重绘的,所以上述两点就很显然会导致大小改变的时候边缘有无效区域或者花屏产生。

  你的临时方案是可行的,但是我还是要推荐你使用下面的WPF MDI解决方案://wpfmdi.codeplex.com/

  他已经很好的实现了父子窗体间的消息传递了。


标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@pclwef.cn

文章转载自:CSDN学生大本营

为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP