我有像这样的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();
线。如前所述,仅仅存在这条线本身就会使父形缩小。我试图在互联网上广泛搜索这个问题。我无法找到解决方案。请帮我解答。我筋疲力尽......
答案 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
Items
和MenuStrip
的{{1}}上的ToolStrip
,因为它们不会收到ScaleControl调用。如果您从未添加过上面的XML,那么仍然会调用此方法,但只会有{1.0,1.0}的因子,这没有用。
注意:如果您正在使用图像列表,那么如果在DesignMode或ImageList中未设置,则不动态设置图像,当您保存时,不会设置任何内容
此外,该因素也不是当前因素。您会注意到,如果您在不同的dpi监视器之间移动应用程序,您将获得2.0,然后是0.5,然后是2.0,然后是0.5,等等。
现在我的WinForms应用程序看起来非常清晰,它可以调用WPF ui元素而不会发疯! yyayyyyy
希望这有助于某人