wpf - 开口WPF用户控件的winform窗口缩小父的winform窗口

标签 wpf winforms winforms-interop

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

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

我还有一个包含此 WPF 用户控件的 win 表单...
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();

线。正如我之前提到的,仅此行本身的存在就会使父窗体缩小。我试图在互联网上广泛搜索这个问题。我无法找到解决方案。请帮我解答。我累极了....

最佳答案

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

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

所以我解决它的方法是告诉 Windows 我将处理 WinForms 缩放。要启用它,您必须将其添加到应用程序 list 中(忽略 dll list )

<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>

您可以添加 list 文件:
Right click on application project -> Add -> New item... -> Application Manifest File
然后在...
Application Project -> Properties -> Application -> Resources
确保“ list ”设置为 app.manifest
您现在可以找到该文件并将上面的 XML 添加到根 <asmv1:assembly> 元素中。

如果您采用了默认的应用程序 list 并添加了该元素,它可能看起来像这样
<?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)。我在第一次尝试解决问题时更改了所有内容以继承缩放模式,这对我有用,如果您使用字体或不使用字体,我怀疑它会起作用,但我还没有尝试过。

由于我的是 200% UI 缩放,当这个方法被调用时 factor 只是 {2.0, 2.0} 然后我用它在 Image s 中重新创建一个缩放的 Button,并增加每个 ImageScalingSize ItemsMenuStripToolStrip,因为它们不接收 ScaleControl 调用。如果您从未添加过上面的 XML,那么该方法仍会被调用,但对于因子只会有 {1.0, 1.0},这没有帮助。
注意:如果您使用的是图像列表,则在 DesignMode 中不要动态设置图像,否则 ImageList 将变为未设置,保存时将不会设置任何内容

也不是那个因素是来自当前的因素。您会注意到,如果您在不同的 dpi 显示器之间移动应用程序,您将获得 2.0、0.5、2.0、0.5 等。

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

希望这有助于某人

关于wpf - 开口WPF用户控件的winform窗口缩小父的winform窗口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26410999/

相关文章:

c# - 如何创建一个在 WPF 中拖动时调整窗口大小的按钮?

c# - 如何在代码中设置按钮的内部属性?

c# - 如何将标签添加到 DataGridView 单元格

c# - 等待文件被进程释放

c# - 如何删除在 webbrowser 控件中导航的文件?

WPF重绘问题

WPF 主题错误 : Cannot resolve all property references in the property path

c# - SciChart FastLineRenderableSeries 抗锯齿不起作用

c# - 在 C++ 中使用 Winform 作为 View

winforms - 是否对 .exe 和 Windows 窗体应用程序中的窗体使用相同的图标而不重复?