打开WPF用户控件winform窗口缩小父winform窗口

时间:2014-10-16 18:03:49

标签: wpf winforms winforms-interop

我有像这样的WPF用户控件......

namespace WpfApplication1
{
    public partial class MyControl : UserControl
    {
    ......
    }
}

我还有一个win表单来包含这个WPF用户控件...

namespace WindowsFormsApplication4
{
public partial class Form1 : Form
{

    public Form1()
    {

        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        ElementHost ctrlHost = new ElementHost();
        ctrlHost.Dock = DockStyle.Fill;
        WpfApplication1.MyControl win = new WpfApplication1.MyControl();
        ctrlHost.Child = win;
        this.Controls.Add(ctrlHost);
    }
}
}

我还有一个带有按钮的父级胜利表格。单击该按钮将打开包含ElementHost的Form1。

namespace WindowsFormsApplication4
{
    public partial class Parent : Form
    {
        public Parent()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Form1 form1 = new Form1();
            form1.Show();

        }
    }
}

我的应用程序默认运行父窗体...

Application.Run(new Parent());

我面临的问题很奇怪。当我运行应用程序时,父窗体打开,单击按钮时,包含WPF控件的子窗口窗体也会打开。但问题是,一旦WPF控件表格弹出,父窗体窗口的大小会自动缩小(窗口移位,恢复自身,控件和字体变小)。如果我评论' Form1_Load'函数然后父窗口不收缩。为了检查最坏的情况,我评论了Form1_Load'中的所有内容。除了

ElementHost ctrlHost = new ElementHost();

线。如前所述,仅仅存在这条线本身就会使父形缩小。我试图在互联网上广泛搜索这个问题。我无法找到解决方案。请帮我解答。我筋疲力尽......

1 个答案:

答案 0 :(得分:11)

我在上面评论说我遇到了同样的问题并且已经解决了。我在这里为其他人写下我的更改。

如上所述,只要在WinForms应用程序中使用Windows UI扩展并且Just In Time(JIT)编译器处理来自WPF库的任何内容,就会出现这种行为。在我的例子中,输入一个包含打开WPF版本的MessageBox的代码的方法将使它成为现实。 通常,Windows将为您处理基本缩放,渲染到屏幕外的位图,然后在屏幕上绘制但按比例放大。当WPF加载它似乎接管,好像它对Windows说,“嘿..我得到了这个......”。之后,Windows停止为您扩展WinForms,最终得到1x缩放版本,并且通常会出现一些混乱的控件。然而,WPF部分正在处理它自己的缩放并且看起来很好。

所以我解决它的方式是告诉Windows我将处理WinForms扩展。要启用它,您必须将其添加到应用程序清单(忽略dll清单)

<asmv3:application>
  <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
    <dpiAware>true</dpiAware>
  </asmv3:windowsSettings>
</asmv3:application>

如果以下部分已经在其中,则取消注释:

<application xmlns="urn:schemas-microsoft-com:asm.v3">
  <windowsSettings>
    <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
  </windowsSettings>
</application>

您可以添加清单文件:

Right click on application project -> Add -> New item... -> Application Manifest File

然后在......

Application Project -> Properties -> Application -> Resources

确保“Manifest”设置为app.manifest

您现在可以找到该文件并将上面的XML添加到根<asmv1:assembly>元素中。

如果你已经使用了默认的应用程序清单并添加了该元素,它可能看起来像这样

<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2"  xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
    <security>
      <applicationRequestMinimum>
        <defaultAssemblyRequest permissionSetReference="Custom" />
        <PermissionSet class="System.Security.PermissionSet" version="1" Unrestricted="true" ID="Custom" SameSite="site" />
      </applicationRequestMinimum>
    </security>
  </trustInfo>
  <asmv3:application>
    <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
      <dpiAware>true</dpiAware>
    </asmv3:windowsSettings>
  </asmv3:application>
</asmv1:assembly>

现在,当你启动WinForms应用程序时,你会发现它更加清晰,因为它以高dpi而不是96dpi渲染,然后按比例放大以填充空间。

您可能会注意到很多图片都缩小了!! 在我的情况下,Buttons,MenuStripItems和ToolStripItems没有按需扩展。

我发现大多数控件都有一个可以覆盖的方法,如下所示

protected override void ScaleControl(SizeF factor, BoundsSpecified specified)
{
    base.ScaleControl(factor, specified);
}

当应用程序启动并从主窗体中过滤控件时调用此方法。我的Windows设置为200%,我的主窗体缩放模式设置为DPI,所有窗体都设置为100%缩放(96dpi)。我在第一次尝试修改问题时改变了所有内容以继承扩展模式,这对我有用,如果你使用字体或者没有我怀疑它会起作用,但我还没有尝试过。

当我调用此方法时,我的UI缩放率为200%factor只是{2.0,2.0},然后我用它在Image中重新创建缩放的Button,并且增加ImageScalingSize ItemsMenuStrip的{​​{1}}上的ToolStrip,因为它们不会收到ScaleControl调用。如果您从未添加过上面的XML,那么仍​​然会调用此方法,但只会有{1.0,1.0}的因子,这没有用。 注意:如果您正在使用图像列表,那么如果在DesignMode或ImageList中未设置,则不动态设置图像,当您保存时,不会设置任何内容

此外,该因素也不是当前因素。您会注意到,如果您在不同的dpi监视器之间移动应用程序,您将获得2.0,然后是0.5,然后是2.0,然后是0.5,等等。

现在我的WinForms应用程序看起来非常清晰,它可以调用WPF ui元素而不会发疯! yyayyyyy

希望这有助于某人