WPF MVVM WinformsHost与OpenGL的控制 [英] WPF MVVM WinformsHost with OpenGL-Control

查看:436
本文介绍了WPF MVVM WinformsHost与OpenGL的控制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个WPF应用程序使用MVVM。在这个应用程序,我需要有一个OpenGL控制(我使用OpenTK)。 WPF中获得的OpenGL目前唯一有效的方法是使用一个WindowsFormsHost。直到这里,没有任何问题。



要添加内容到我的场景,我需要在我看来获得了OpenGL的控制。当然,我想添加和编辑视图模型的内容。所以,我怎样才能在不违反MVVM点模式访问OpenGL的控制?



我使用它可以在观统领初始化的场景对象,然后需要以某种方式传输到视图模型。我试过WindowsFormsHost这个使用标签属性,但没有成功(下比较)。在视图模型的属性不会得到更新。



任何想法?



XAML

 <用户控件X:类=FancyOpenGlControl
的xmlns =http://schemas.microsoft。 COM / WinFX的/ 2006 / XAML /演示
的xmlns:X =http://schemas.microsoft.com/winfx/2006/xaml>
< WindowsFormsHost X:NAME =WindowsFormsHost标签={结合场景,模式=双向,UpdateSourceTrigger =的PropertyChanged}/>
< /用户控件>



C#



 公共FancyOpenGlControl()
{
this.InitializeComponent();

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

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

私人无效GlControlOnHandleCreated(对象发件人,EventArgs EventArgs的)
{
this.WindowsFormsHost.Tag =新场景(this.glControl);

//不行的。
// BindingExpression bindingExpression = this.WindowsFormsHost.GetBindingExpression(TagProperty);
//如果(!bindingExpression = NULL)
// {
// bindingExpression.UpdateSource();
//}
}


解决方案

有我能想到的两种选择。



1)直接从视图代码后面设置您的视图模型属性。您需要做响应视图的 DataContextChanged仅事件,因为您的视图模型将不会被尚未在视图的构造勾搭上了。这也意味着铸的DataContext 来已知类型的ViewModel的。我真的没有与该有的却存在问题。

 私人无效FancyOpenGlControl_DataContextChanged(对象发件人,DependencyPropertyChangedEventArgs E)
{
VAR VM = this.DataContext为MyViewModel;

如果(VM!= NULL)
vm.GlControl = this.glControl;
}



2)如果你喜欢稍微更松散的耦合,那么你可以创建一个依赖属性对你的看法,只是你glControl在创建其分配给。然后,您可以将属性绑定到你想就像正常的任何视图模型属性。例如:



后面的代码:

 公共静态只读新的DependencyProperty GControlProperty = 
DependencyProperty.Register(GLControl的typeof(OpenGLControl)的typeof(FancyOpenGlControl),新PropertyMetadata(NULL));

公共OpenGLControl GLControl
{
{返回(OpenGLControl)的GetValue(DocumentProperty); }
集合{的SetValue(GLControlProperty,值); }
}

公共FancyOpenGlControl()
{
this.InitializeComponent();

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



XAML:

 <用户控件X:类=FancyOpenGlControl
的xmlns =http://schemas.microsoft.com/winfx/2006/xaml/presentation
的xmlns :X =http://schemas.microsoft.com/winfx/2006/xaml
GLControl ={结合VMControlProperty}>
< WindowsFormsHost X:NAME =WindowsFormsHost/>




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();
    //}
}

解决方案

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

这篇关于WPF MVVM WinformsHost与OpenGL的控制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆