WPF MVVM WinformsHost with OpenGL-Control

不问归期 提交于 2019-12-23 21:05:09

问题


I'm developing a WPF-application with MVVM. In this application I need to have an OpenGL-Control (I'm using OpenTK). The currently only useful way to get OpenGL in WPF is using a WindowsFormsHost. Until here, there's no problem.

To add content to my Scene I need access to the OpenGL-Control in my View. Of course I want to add and edit the content in the ViewModel. So, how can I get access to the OpenGL-Control without violating the MVVM-Pattern?

I'm using a scene-object which can get initialized in the View and then needs to be transferred somehow to the ViewModel. I tried this using the Tag-property of the WindowsFormsHost but without success (compare below). The property in the ViewModel is not getting updated.

Any ideas?

XAML

<UserControl x:Class="FancyOpenGlControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">    
    <WindowsFormsHost x:Name="WindowsFormsHost" Tag="{Binding Scene, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</UserControl>

C#

public FancyOpenGlControl()
{
    this.InitializeComponent();

    this.glControl = new OpenGLControl();
    this.glControl.Dock = DockStyle.Fill;
    this.WindowsFormsHost.Child = this.glControl;

    this.glControl.HandleCreated += this.GlControlOnHandleCreated;
}

private void GlControlOnHandleCreated(object sender, EventArgs eventArgs)
{
    this.WindowsFormsHost.Tag = new Scene(this.glControl);

    // Doesn't work.
    //BindingExpression bindingExpression = this.WindowsFormsHost.GetBindingExpression(TagProperty);
    //if (bindingExpression != null)
    //{
    //    bindingExpression.UpdateSource();
    //}
}

回答1:


There are two options I can think of.

1) Set your viewmodel property directly from the view code behind. You will need to do this in response to the view's DataContextChanged event, since your ViewModel won't be hooked up yet in the view's constructor. This will also mean casting the DataContext to a known type of ViewModel. I don't really have a problem with that but some do.

private void FancyOpenGlControl_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
    var vm = this.DataContext as MyViewModel;

    if (vm != null)
        vm.GlControl = this.glControl;
}

2) If you prefer slightly looser coupling, then you can create a dependency property on your view and just assign your glControl to that when you create it. You can then bind the property to any ViewModel property you want just like normal. eg:

Code behind:

public static readonly new DependencyProperty GControlProperty =
    DependencyProperty.Register("GLControl", typeof(OpenGLControl), typeof(FancyOpenGlControl), new PropertyMetadata(null));

public OpenGLControl GLControl
{
    get { return (OpenGLControl )GetValue(DocumentProperty); }
    set { SetValue(GLControlProperty , value); }
}

public FancyOpenGlControl()
{
    this.InitializeComponent();

    this.GLControl= new OpenGLControl();
    this.GLControl.Dock = DockStyle.Fill;
    this.WindowsFormsHost.Child = this.GLControl;
}

XAML:

<UserControl x:Class="FancyOpenGlControl"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            GLControl="{Binding VMControlProperty}">    
    <WindowsFormsHost x:Name="WindowsFormsHost"/>



来源:https://stackoverflow.com/questions/23733822/wpf-mvvm-winformshost-with-opengl-control

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!