C#/XAML应用程序中,如何绑定属于WindowsFormsHost子对象的属性?有什么解决方法?

4
我是一位有用的助手,可以为您翻译文本。以下是需要翻译的内容:

我有一个使用C# WPF 4.51编写的应用程序。据我所知,您无法绑定到属于WPF WindowsFormsHost控件子级的对象的属性。(如果我的假设不正确,请告诉我如何做):

与WindowsFormsHost绑定

在我的情况下,我有一个包含WindowsFormsHost控件的页面,其Child对象是一个ScintillaNET编辑器控件:

https://github.com/jacobslusser/ScintillaNET

    <WindowsFormsHost x:Name="wfhScintillaTest"
                      Width="625"
                      Height="489"
                      Margin="206,98,0,0"
                      HorizontalAlignment="Left"
                      VerticalAlignment="Top">
        <WindowsFormsHost.Child>
            <sci:Scintilla x:Name="scintillaCtl" />
        </WindowsFormsHost.Child>
    </WindowsFormsHost>

孩子控件运作良好且显示正常。如果它是普通的WPF控件,我会将Scintilla编辑器控件的Text属性绑定到ViewModel中的某个字符串属性,这样我只需更新该字符串属性即可更新Scintilla编辑器控件的内容。
但由于无法绑定到属于WindowsFormsHost子对象的属性,因此我正在寻找一种不完全笨拙或混乱的策略/解决方案。是否有人遇到过这种情况,并有一个合理的策略来解决我的绑定/更新问题?

WinForm的控件属性是如何设置的?也许可以在您的VM中公开设置它的任何设置? - user585968
3个回答

7
一个简单的方法是创建一些专门的类,只包含映射到winforms控件属性的附加属性。在这种情况下,我选择

为什么要使用静态容器类和底层属性,而不是普通的容器类和属性?(例如:https://dev59.com/v2gu5IYBdhLWcg3wln4O)。在这个SO帖子中,DependencyProperty声明是静态的,但它公开的属性和主机类不是。我想知道这两种方法之间的区别是什么?谢谢。 - Robert Oschler
1
@RobertOschler 针对UserControl,您可以访问其类并添加一些实例属性(依赖属性的包装器)。但是在这里,WindowsFormsHost不是您的类,因此使用附加属性是一种方便的方式。如果您想要,可以对其进行子类化并在那里声明您的属性,并且当然可以使用该类而不是WindowsFormsHost - King King

1
你只能在Windows Forms控件中实现非常有限的绑定,因为绑定不会接收更新通知,并且可能需要通过自定义的RefreshValues()方法或轮询每个数据来显式地获取结果。
但是,如果你只需要访问子控件,你应该在代码中进行绑定:
(WFH.Child as MyWinFormsControl).Text

如果您打算进行大量的绑定,可能更容易创建一个WPF包装对象(UserControl),该对象具有所有需要的属性作为DependencyProperties,并且每个属性的底层代码将手动轮询WinForms控件,就好像它是属性的后备字段一样。起初有点复杂,但比手动轮询每个属性要容易得多。

1
“与 Windows Forms 控件的绑定非常有限,因为它们的绑定不会接收更新通知” - 你确定吗?INotifyPropertyChanged早于WPF。 - user585968
我可能错了(如果是这样就太好了 :) - 但我主要是从个人经验出发说话。虽然属性通知确实存在,但它们没有被正确更新,因此我们制作了包装器。 - Dax Pandhi

-2
创建一个类型为Windows Form Host的依赖对象。
using System.Windows.Forms.Integration;

namespace MainStartUp.DependencyObjects
{
    public class FormHostDependencyObject : WindowsFormsHost
    {
        public static readonly DependencyProperty ContentControlProperty =
            DependencyProperty.Register("ContentControl", typeof(System.Windows.Forms.Control), 
                typeof(FormHostDependencyObject),
                new PropertyMetadata(new System.Windows.Forms.Control(), PropertyChaged));       

        public static void SetContentControl(UIElement element, string value)
        {  
            element.SetValue(ContentControlProperty, value);          
        }

        public static string GetContentControl(UIElement element)
        {
            return (string)element.GetValue(ContentControlProperty);
        }

        private static void PropertyChaged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
        {
            ((FormHostDependencyObject)dependencyObject).Child = (System.Windows.Forms.Control)e.NewValue;
        }
    }
}

请正确格式化您的答案。似乎您的一些代码在“代码框”之外。 - L. Guthardt
在SO上输入/编辑问题和答案时,您会自动获得实时更新的预览。在决定提交内容之前,请查看预览并检查是否一切正常。 - Nyerguds

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接