是否可以从WPF用户控件显示模态窗口,它是ElementHost的子级,并将模态窗口的所有者/父级设置为包含的Form控件?
我猜你不能这样做,因为Owner属性采用了Window的一个实例,我想把它设置为Element Host控件的父级,这是一个旧的Windows Forms Form控件.只是想知道是否有解决方法或替代方法.
问题是当显示模态窗口并且用户切换到另一个应用程序,然后再返回时,模态窗口被隐藏,用户无法与主窗口交互.这是因为Windows认为模态窗口仍然显示,而不是,因为没有设置所有者/父关系.
干杯,詹姆斯.
我在WinForms容器中托管WPF UserControl.现在,我希望能够主题/皮肤UserControl.为此,我有几个定义"皮肤"的资源字典.当我的应用程序启动时,我创建了一个"new System.Windows.Application()",以便Application.Current存在.要更改主题,将删除旧外观,并在运行时将新外观合并到应用程序级别资源字典中.但是,这不会更改UserControl中任何dyanamically引用的资源.我在一个直接的WPF应用程序中尝试了这个,它运行得很好.我错过了什么,或者根本不可能这样做?顺便说一句,如果我在UserControl初始化之前将一个皮肤添加到应用程序资源中,它将起作用,但之后我无法更改皮肤.
以最基本的方式回复这个:
创建一个新的WinForms应用程序.将WPF UserControl添加到应用程序.这很简单:
<UserControl ...>
<Grid>
<Button
Background="{DynamicResource ButtonBG}"/>
</Grid>
</UserControl>
Run Code Online (Sandbox Code Playgroud)
使用具有相应颜色的键ButtonBG创建两个具有SolidColorBrush的ResourceDictionaries,White.xaml和Black.xaml(或其他).在Form1.cs中,添加两个按钮和一个ElementHost.将ElementHost的子项设置为我们刚刚创建的UserControl的实例.将按钮连接到交换皮肤的事件:
private void White_Click(object sender, EventArgs e)
{
Application.Current.Resources.MergedDictionaries[0] =
(ResourceDictionary)Application.LoadComponent(
new Uri(@"\WpfThemes;component\White.xaml", UriKind.Relative)));
}
private void Black_Click(object sender, EventArgs e)
{
Application.Current.Resources.MergedDictionaries[0] =
(ResourceDictionary)Application.LoadComponent(
new Uri(@"\WpfThemes;component\Black.xaml", UriKind.Relative)));
}
Run Code Online (Sandbox Code Playgroud)
在Program.cs中,确保Application.Current存在并设置初始外观:
[STAThread]
static void Main()
{
new System.Windows.Application();
Application.Current.Resources.MergedDictionaries[0] =
(ResourceDictionary)Application.LoadComponent(
new Uri(@"\WpfThemes;component\White.xaml", UriKind.Relative)));
...
}
Run Code Online (Sandbox Code Playgroud)
现在,当单击白色按钮时,我希望UserControl中的按钮变为白色,当单击黑色按钮时,我希望按钮变黑.但是,这不会发生.
有谁知道为什么?有解决方案吗?
编辑:想法:也许,如果有一种方法可以在主题发生变化时强制重新评估DynamicResources,那就行了.
谢谢,Dusty
有一个在我们的WinForms托管WPF应用程序内存泄漏FlowDocumentReader的一个ElementHost.我在一个简单的项目中重新创建了这个问题,并添加了下面的代码.
当我按下button1:
UserControl1只包含a的A FlowDocumentReader被创建并设置为ElementHost'sChildFlowDocument是从文本文件创建的(它只包含一个FlowDocument带有StackPanel几千行的文件<TextBox/>)FlowDocumentReader的Document属性设置为这FlowDocument此时,页面呈现FlowDocument正确.正如预期的那样,使用了大量内存.
如果button1再次单击,则内存使用量会增加,并且每次重复该过程时都会不断增加!尽管使用了大量新内存,GC仍未收集!没有参考不应该存在,因为:
如果我按下button2哪个设置elementHost1.Child为null并调用GC(参见下面的代码),则会发生另一个奇怪的事情 - 它不会清理内存,但如果我继续点击它几秒钟,它最终将释放它!
我们所有这些记忆都被使用是不可接受的.此外,ElementHost从Controls集合中删除Disposing它,将引用设置为null,然后调用GC不会释放内存.
button1点击多次,内存使用量不应该继续增加这不是内存使用无关紧要的事情,我可以随时让GC收集它.它实际上最终明显减慢了机器的速度.
如果你只是想下载VS项目,我已经在这里上传了它:http: //speedy.sh/8T5P2/WindowsFormsApplication7.zip
否则,这是相关代码.只需在设计器中为表单添加2个按钮,然后将它们连接到事件即可.Form1.cs中:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using …Run Code Online (Sandbox Code Playgroud) 我需要在Winform用户控件上托管WPF控件.为此,我使用了ElementHost控件.当我运行Ants Memory分析器时,我知道ElementHost控件中存在大量内存泄漏.请在下面找到附加的保留图,并帮助我修复Memoryleak.
这是我在StackOverflow中的第一个问题。由于缺乏声誉,我无法发布任何链接或图像。我处理以下问题已经超过2天。任何帮助将不胜感激。
在我提出问题之前,这是我所拥有的和期望的:
由于以下原因,上述情况是不可避免的:
预期功能:
我有一个
WPF控件(例如,一个文本框)
我上面提到的DateTime Winforms UserControl。
还有一个“取消”按钮,基本上可以重设以上控件。
当我打的取消按钮,我发布从一个事件ViewModel,说RunViewModel到WPF用户控件隐藏文件的代码,说RunView.xaml.cs。
eventAggregator.GetEvent<ResetDateTimeEvent>().Publish(true);
Run Code Online (Sandbox Code Playgroud)
在文件背后的代码中,我已订阅该事件,如下所示
eventAggregator.GetEvent<ResetDateTimeEvent>().Subscribe(ResetDateTimeHandler);
Run Code Online (Sandbox Code Playgroud)
该WPF控件重置为默认值,但日期时间用户控件 也无法复位。
因此,出于测试目的,我删除了ElementHost控件,只使用了带有WindowsFormsHost控件的WPF视图,该控件承载DateTime Winforms UserControl和WPF“取消”按钮。
当我单击按钮时,DateTime控件上的值将重置为其默认值。
然后,我认为这可能是我的DateTime Winforms UserControl的问题。因此,在我的实际应用程序中,我用Winforms Textbox控件替换了DateTime Winforms UserControl 。所以现在嵌套如下:
WinForms-ElementHost-WPF-WindowsFormsHost-Winforms文本框
这是xaml代码。
<WindowsFormsHost x:Name="ReportFromDtTmHost" Margin="8,0" Grid.Column="0"
LostFocus="ReportFromDtTmHost_LostFocus">
<WindowsFormsHost.Child>
<winforms:TextBox x:Name="ReportFromDateTime"/>
</WindowsFormsHost.Child>
</WindowsFormsHost>
Run Code Online (Sandbox Code Playgroud)
在初始加载时,我正在加载Textbox …
好奇如果使用ElementHost在Winform应用程序中托管WPF UserControl 有什么缺点吗?
我问,因为总的来说我觉得我需要花很多时间创建一个新的WPF应用程序,其基本界面看起来不错.从某种意义上讲,如果我创建一个新的Winforms应用程序并对其进行一些控制,我最终会得到一个基本界面,其外观和行为类似于许多其他应用程序,但看起来并不简单.如果我对WPF应用程序做同样的事情,我觉得我没有达到相同的结果,我最终得到一个白色背景的"普通"应用程序,除非我将角色更改为设计师并花费额外的时间使其看起来确定办法.
但是有些情况下WPF对我来说是可取的,因为它相对容易创建一个风格化的界面.考虑视频播放器控件; 在WPF中,我可以创建看起来非常漂亮和自定义的东西,但比Winforms控件花费的时间和精力要少得多.在这些情况下,我使用WPF是有道理的,因为我最终花费的时间少于覆盖OnPaint的时间:-).
我意识到我使用了很多主观术语,但这是我在原始问题背后的推理.
更新:
只是为了澄清我的"视频播放器控制"示例.WPF不仅可以让我MediaElement玩,而且如果我想说,暂停时在视频上叠加一个播放按钮,或者我想要一个半透明的"播放/暂停/停止/音量"栏来显示鼠标在某个位置,WPF比任何Winforms替代方案都简单得多.
编辑:
也许我有一个错误的配置选项或者其他东西,但是当我查看WPF与Winforms控件时,"描述"部分的消失也令人沮丧.更加令人沮丧的是,在WPF属性表单中按F1并不会将您带到您所在的特定属性/事件.
更新:
还有谁?我更关注通过在ElementHost中托管WPF UserControl而引入的性能影响和/或功能限制.到目前为止,它听起来像是运行时的一次性开销,但这就是全部吗?
我正在WinForms应用程序的一侧构建一组WPF控件,以便我最终可以将整个项目转换为WPF.我正在使用WinForms ElementHost模块并在其中设置我的WPF控件.
这是我的问题,我已经通过ElementHost在WinForms应用程序上托管了大量的WPF控件.但是,我遇到了这个控件,它告诉我:
Error setting value'Assembly.MyCustomControl' to property 'Child'. Details:
Could not load type 'Assembly.MyCustomControl' from assembly 'Assembly'......
Run Code Online (Sandbox Code Playgroud)
我再一次以同样的方式将几个其他控件加载到这个项目中.托管控件的库绝对没有错误.我在这里亏本.
在我尝试将ElementHost设置为控件后,此错误也会在WinForms设计器上显示.
at System.Reflection.RuntimeAssembly.GetType(RuntimeAssembly assembly, String name, Boolean throwOnError, Boolean ignoreCase, ObjectHandleOnStack type)
at System.Reflection.RuntimeAssembly.GetType(String name, Boolean throwOnError, Boolean ignoreCase)
at System.UnitySerializationHolder.GetRealObject(StreamingContext context)
at System.ComponentModel.ReflectPropertyDescriptor.SetValue(Object component, Object value)
at System.ComponentModel.Design.Serialization.CodeDomSerializerBase.DeserializePropertyAssignStatement(IDesignerSerializationManager manager, CodeAssignStatement statement, CodePropertyReferenceExpression propertyReferenceEx, Boolean reportError)
at System.ComponentModel.Design.Serialization.CodeDomSerializerBase.DeserializeAssignStatement(IDesignerSerializationManager manager, CodeAssignStatement statement)
at System.ComponentModel.Design.Serialization.CodeDomSerializerBase.DeserializeStatement(IDesignerSerializationManager manager, CodeStatement statement)
Run Code Online (Sandbox Code Playgroud)
编辑
我稍后会将此作为答案发布,但重新启动Visual Studio修复了问题...
我在使用ElementHost的WinForms中使用WPF.当表单加载时,有一个黑色背景闪烁,ElementHost即将加载.这看起来很糟糕.有关如何摆脱这个的任何建议?
elementhost ×8
wpf ×7
winforms ×5
c# ×2
.net ×1
flowdocument ×1
mvvm ×1
owner ×1
prism ×1
showdialog ×1
wpf-controls ×1