演练:在 Windows 窗体中托管 3D WPF 复合控件

本演练演示如何通过使用 ElementHost 控件创建 WPF 复合控件并将其托管在 Windows 窗体控件和窗体中。

在本演练中,你将实现一个包含两个子控件的 WPF UserControlUserControl 显示一个三维(3D)圆锥。 与使用 Windows 窗体相比,使用 WPF 呈现 3D 对象要容易得多。 因此,托管 WPF UserControl 类在 Windows 窗体中创建 3D 图形是有意义的。

本演练涉及以下任务:

先决条件

需要以下组件才能完成本演练:

  • Visual Studio 2017

创建用户控件

  1. 创建名为 .. 的 HostingWpfUserControlInWfWPF 用户控件库项目。

  2. 在 WPF 设计器中打开 UserControl1.xaml。

  3. 将生成的代码替换为以下代码:

    <UserControl x:Class="HostingWpfUserControlInWf.UserControl1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        >
      
        <Grid>
    
          <!-- Place a Label control at the top of the view. -->
          <Label 
                    HorizontalAlignment="Center" 
                    TextBlock.TextAlignment="Center" 
                    FontSize="20" 
                    Foreground="Red" 
                    Content="Model: Cone"/>
    
          <!-- Viewport3D is the rendering surface. -->
          <Viewport3D Name="myViewport" >
    
            <!-- Add a camera. -->
            <Viewport3D.Camera>
              <PerspectiveCamera 
                            FarPlaneDistance="20" 
                            LookDirection="0,0,1" 
                            UpDirection="0,1,0" 
                            NearPlaneDistance="1" 
                            Position="0,0,-3" 
                            FieldOfView="45" />
            </Viewport3D.Camera>
    
            <!-- Add models. -->
            <Viewport3D.Children>
    
              <ModelVisual3D>
                <ModelVisual3D.Content>
    
                  <Model3DGroup >
                    <Model3DGroup.Children>
    
                      <!-- Lights, MeshGeometry3D and DiffuseMaterial objects are added to the ModelVisual3D. -->
                      <DirectionalLight Color="#FFFFFFFF" Direction="3,-4,5" />
    
                      <!-- Define a red cone. -->
                      <GeometryModel3D>
    
                        <GeometryModel3D.Geometry>
                          <MeshGeometry3D 
        Positions="0.293893 -0.5 0.404509  0.475528 -0.5 0.154509  0 0.5 0  0.475528 -0.5 0.154509  0 0.5 0  0 0.5 0  0.475528 -0.5 0.154509  0.475528 -0.5 -0.154509  0 0.5 0  0.475528 -0.5 -0.154509  0 0.5 0  0 0.5 0  0.475528 -0.5 -0.154509  0.293893 -0.5 -0.404509  0 0.5 0  0.293893 -0.5 -0.404509  0 0.5 0  0 0.5 0  0.293893 -0.5 -0.404509  0 -0.5 -0.5  0 0.5 0  0 -0.5 -0.5  0 0.5 0  0 0.5 0  0 -0.5 -0.5  -0.293893 -0.5 -0.404509  0 0.5 0  -0.293893 -0.5 -0.404509  0 0.5 0  0 0.5 0  -0.293893 -0.5 -0.404509  -0.475528 -0.5 -0.154509  0 0.5 0  -0.475528 -0.5 -0.154509  0 0.5 0  0 0.5 0  -0.475528 -0.5 -0.154509  -0.475528 -0.5 0.154509  0 0.5 0  -0.475528 -0.5 0.154509  0 0.5 0  0 0.5 0  -0.475528 -0.5 0.154509  -0.293892 -0.5 0.404509  0 0.5 0  -0.293892 -0.5 0.404509  0 0.5 0  0 0.5 0  -0.293892 -0.5 0.404509  0 -0.5 0.5  0 0.5 0  0 -0.5 0.5  0 0.5 0  0 0.5 0  0 -0.5 0.5  0.293893 -0.5 0.404509  0 0.5 0  0.293893 -0.5 0.404509  0 0.5 0  0 0.5 0  " 
        Normals="0.7236065,0.4472139,0.5257313  0.2763934,0.4472138,0.8506507  0.5308242,0.4294462,0.7306172  0.2763934,0.4472138,0.8506507  0,0.4294458,0.9030925  0.5308242,0.4294462,0.7306172  0.2763934,0.4472138,0.8506507  -0.2763934,0.4472138,0.8506507  0,0.4294458,0.9030925  -0.2763934,0.4472138,0.8506507  -0.5308242,0.4294462,0.7306172  0,0.4294458,0.9030925  -0.2763934,0.4472138,0.8506507  -0.7236065,0.4472139,0.5257313  -0.5308242,0.4294462,0.7306172  -0.7236065,0.4472139,0.5257313  -0.858892,0.429446,0.279071  -0.5308242,0.4294462,0.7306172  -0.7236065,0.4472139,0.5257313  -0.8944269,0.4472139,0  -0.858892,0.429446,0.279071  -0.8944269,0.4472139,0  -0.858892,0.429446,-0.279071  -0.858892,0.429446,0.279071  -0.8944269,0.4472139,0  -0.7236065,0.4472139,-0.5257313  -0.858892,0.429446,-0.279071  -0.7236065,0.4472139,-0.5257313  -0.5308242,0.4294462,-0.7306172  -0.858892,0.429446,-0.279071  -0.7236065,0.4472139,-0.5257313  -0.2763934,0.4472138,-0.8506507  -0.5308242,0.4294462,-0.7306172  -0.2763934,0.4472138,-0.8506507  0,0.4294458,-0.9030925  -0.5308242,0.4294462,-0.7306172  -0.2763934,0.4472138,-0.8506507  0.2763934,0.4472138,-0.8506507  0,0.4294458,-0.9030925  0.2763934,0.4472138,-0.8506507  0.5308249,0.4294459,-0.7306169  0,0.4294458,-0.9030925  0.2763934,0.4472138,-0.8506507  0.7236068,0.4472141,-0.5257306  0.5308249,0.4294459,-0.7306169  0.7236068,0.4472141,-0.5257306  0.8588922,0.4294461,-0.27907  0.5308249,0.4294459,-0.7306169  0.7236068,0.4472141,-0.5257306  0.8944269,0.4472139,0  0.8588922,0.4294461,-0.27907  0.8944269,0.4472139,0  0.858892,0.429446,0.279071  0.8588922,0.4294461,-0.27907  0.8944269,0.4472139,0  0.7236065,0.4472139,0.5257313  0.858892,0.429446,0.279071  0.7236065,0.4472139,0.5257313  0.5308242,0.4294462,0.7306172  0.858892,0.429446,0.279071  "                   TriangleIndices="0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 " />
                        </GeometryModel3D.Geometry>
    
                        <GeometryModel3D.Material>
                          <DiffuseMaterial>
                            <DiffuseMaterial.Brush>
                              <SolidColorBrush 
                                Color="Red" 
                                Opacity="1.0"/>
                            </DiffuseMaterial.Brush>
                          </DiffuseMaterial>
                        </GeometryModel3D.Material>
    
                      </GeometryModel3D>
    
                    </Model3DGroup.Children>
                  </Model3DGroup>
    
                </ModelVisual3D.Content>
    
              </ModelVisual3D>
    
            </Viewport3D.Children>
    
          </Viewport3D>
        </Grid>
      
    </UserControl>
    

    此代码定义包含两个子控件的控件 System.Windows.Controls.UserControl 。 第一个子控件是一个 System.Windows.Controls.Label 控件;第二个 Viewport3D 控件是显示 3D 圆锥的控件。

创建主机项目

  1. 将名为WpfUserControlHostWindows 窗体应用(.NET Framework)项目添加到解决方案中。

  2. 解决方案资源管理器中,添加对名为 WindowsFormsIntegration.dll的 WindowsFormsIntegration 程序集的引用。

  3. 添加对以下 WPF 程序集的引用:

    • PresentationCore

    • PresentationFramework

    • WindowsBase

  4. 添加对 HostingWpfUserControlInWf 项目的引用。

  5. 在解决方案资源管理器中,将 WpfUserControlHost 项目设置为启动项目。

托管用户控件

  1. 在 Windows 窗体设计器中,打开 Form1。

  2. 在“属性”窗口中,单击“ 事件”,然后双击该 Load 事件以创建事件处理程序。

    代码编辑器将打开到新生成的 Form1_Load 事件处理程序。

  3. 将Form1.cs中的代码替换为以下代码。

    Form1_Load事件处理程序创建一个实例UserControl1并将其添加到ElementHost控件的子控件集合中。 该 ElementHost 控件将添加到窗体的子控件集合中。

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    
    using System.Windows.Forms.Integration;
    
    namespace WpfUserControlHost
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                // Create the ElementHost control for hosting the
                // WPF UserControl.
                ElementHost host = new ElementHost();
                host.Dock = DockStyle.Fill;
    
                // Create the WPF UserControl.
                HostingWpfUserControlInWf.UserControl1 uc =
                    new HostingWpfUserControlInWf.UserControl1();
    
                // Assign the WPF UserControl to the ElementHost control's
                // Child property.
                host.Child = uc;
    
                // Add the ElementHost control to the form's
                // collection of child controls.
                this.Controls.Add(host);
            }
        }
    }
    
    Imports System.Collections.Generic
    Imports System.ComponentModel
    Imports System.Data
    Imports System.Drawing
    Imports System.Text
    Imports System.Windows.Forms
    
    Imports System.Windows.Forms.Integration
    
    Public Class Form1
        Inherits Form
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            ' Create the ElementHost control for hosting the
            ' WPF UserControl.
            Dim host As New ElementHost()
            host.Dock = DockStyle.Fill
    
            ' Create the WPF UserControl.
            Dim uc As New HostingWpfUserControlInWf.UserControl1()
    
            ' Assign the WPF UserControl to the ElementHost control's
            ' Child property.
            host.Child = uc
    
            ' Add the ElementHost control to the form's
            ' collection of child controls.
            Me.Controls.Add(host)
        End Sub
    
    End Class
    
  4. F5 生成和运行应用程序。

另请参阅