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

bal*_*aji 12 wpf winforms-interop winforms

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

namespace WpfApplication1
{
    public partial class MyControl : UserControl
    {
    ......
    }
}
Run Code Online (Sandbox Code Playgroud)

我还有一个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);
    }
}
}
Run Code Online (Sandbox Code Playgroud)

我还有一个父按钮,有一个按钮.单击该按钮将打开包含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();

        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Application.Run(new Parent());
Run Code Online (Sandbox Code Playgroud)

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

ElementHost ctrlHost = new ElementHost();
Run Code Online (Sandbox Code Playgroud)

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

dte*_*ten 13

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

如上所述,只要在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>
Run Code Online (Sandbox Code Playgroud)

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

<application xmlns="urn:schemas-microsoft-com:asm.v3">
  <windowsSettings>
    <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
  </windowsSettings>
</application>
Run Code Online (Sandbox Code Playgroud)

您可以添加清单文件:

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>
Run Code Online (Sandbox Code Playgroud)

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

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

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

protected override void ScaleControl(SizeF factor, BoundsSpecified specified)
{
    base.ScaleControl(factor, specified);
}
Run Code Online (Sandbox Code Playgroud)

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

正如我的是200%UI缩放当此方法被称为factor只是{2.0,2.0}我然后用于重新缩放ImageButtonS,并增加ImageScalingSize在每个的ItemsMenuStripToolStrip,因为这些不接收ScaleControl呼叫.如果您从未添加过上面的XML,那么仍​​然会调用此方法,但只会有{1.0,1.0}的因子,这没有用.注意:如果您正在使用图像列表,那么如果在DesignMode或ImageList中取消设置,则不动态设置图像,当您保存时,不会设置任何内容

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

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

希望这有助于某人