WPF应用中对WindowsFormHost内容进行裁剪

Posted duel

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WPF应用中对WindowsFormHost内容进行裁剪相关的知识,希望对你有一定的参考价值。

问题1: 

  WPF中在使用WindowsFormsHost调用WinFrom控件时,若在WindowsFormsHost上层添加了WPF控件,该控件不会显示出来。

 <Grid>
    <WindowsFormsHost Background="White">
          <Winfrm:WebBrowser x:Name="WinFrmWebBrowser"/>
    </WindowsFormsHost>
    <!--运行时 Ellipse 不会显示出来-->
    <Ellipse Width="100" Height="100" Fill="Red"/>
 </Grid>

技术图片?

解决方案: 使用Popup对上层的WPF控件内容进行包装。

<Style TargetType="x:Type local:MyBrowser">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="x:Type local:MyBrowser">
                <Border Background="TemplateBinding Background"
                        BorderBrush="TemplateBinding BorderBrush"
                        BorderThickness="TemplateBinding BorderThickness">
                    <Grid>
                        <Border x:Name="Part_BdrWinfrmHostContainer">
                            <WindowsFormsHost x:Name="Part_WinfrmHost" Background="Gray">
                                <Winfrm:WebBrowser x:Name="Part_WinFrmWebBrowser"/>
                            </WindowsFormsHost>
                        </Border>
                        <Popup x:Name="PART_Popup" IsOpen="True" Placement="Center" 
                               AllowsTransparency="True">
                            <!--所有WPF内容添加至这个Border里面-->
                            <Border x:Name="PART_Content"/>
                        </Popup>
                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

 我测试时封装成了自定义的CustomControl。 对应的.cs文件中定义了Link、 Content两个依赖属性接收参数。

<Grid x:Name="GdPopupWays" Grid.Column="1">
    <local:MyBrowser Link="http://www.baidu.com">
        <local:MyBrowser.Content>
            <!--local:OverLayer是自定义的UserControl-->
            <local:OverLayer/>
        </local:MyBrowser.Content>
    </local:MyBrowser>
</Grid>

技术图片?

如右侧,我创建了一个黄色的Ellipse叠加在WindowsFormHost 上面成功呈现出来。(tips:我在WindowsFormHost 里面加载了WinForm的WebBrowser)。

问题2:

想要将加载在WindowsFormHost中的内容进行裁剪。

解决方案:WinForm控件的Region属性限制显示区域。 相当于WPF的Clip。 示例如下:

GraphicsPath path = new GraphicsPath()  FillMode = FillMode.Winding ;
path.StartFigure();
path.AddEllipse(new System.Drawing.Rectangle(0, 0, (int)182, (int)182));
path.AddRectangle(new System.Drawing.Rectangle(90, 0, 90, 90));
path.CloseFigure();
this.WinformRtx.Region = new Region(path);

我的测试效果,WPF中用Image加载了一张星空图,右上角放置了WindowsFormHost内容。我对其进行了显示区域限制。

技术图片?

技术图片

3:问题三

   两个WindowsFormHost叠加时,WindowsFormHost对于png的背景图不支持透明。如下图:

<Grid x:Name="GdMain">
    <Image x:Name="ImgSky" Source="Sky.jpg" Stretch="Fill"/>

    <!--加载Winform的WebBrowser-->
    <WindowsFormsHost Background="White">
        <Winfrm:WebBrowser x:Name="WinFrmWebBrowser"/>
    </WindowsFormsHost>

    <WindowsFormsHost Width="182" Height="182" HorizontalAlignment="Right" 
                      x:Name="WinfrmHostOverlayer" VerticalAlignment="Top" 
                      Background="Transparent">
        <Winfrm:Panel x:Name="WinfrmPanel"/>
    </WindowsFormsHost>
</Grid>

技术图片?

可以看到右上角的png边框分明(实时上我放的是一张三个角均为透明的圆形png)。 若对右上角的Winform Panel进行裁剪。

技术图片?

裁剪完后,下面一层的WindowsFormHost也被裁了,露出了我用Image加载的星空底图,如下图:

技术图片?

技术图片

解决方案:将要加载的Winform控件放在一起,可以是在同一个Winform Panel下面,这时在进行裁剪就不会有问题。

<Grid x:Name="GdMain">
    <Image x:Name="ImgSky" Source="Sky.jpg" Stretch="Fill"/>
    <WindowsFormsHost HorizontalAlignment="Right" 
                      x:Name="WinfrmHostOverlayer" VerticalAlignment="Top" 
                      Background="Transparent">
        <Winfrm:Panel x:Name="WinfrmPanel">
            <!--<Winfrm:WebBrowser x:Name="WinFrmWebBrowser"/>-->
            <!--<Winfrm:Panel x:Name="WinFrmSubPanel"/>-->
        </Winfrm:Panel>
    </WindowsFormsHost>
</Grid>

 上文中WebBrowser我都加载的是www.baidu.com.  为了凸显效果,下图所示Demo加载的是腾讯企业邮箱主页。

技术图片?

源代码下载链接:微信扫描下方二维码文章末尾获取链接。

                                技术图片?

技术图片

以上是关于WPF应用中对WindowsFormHost内容进行裁剪的主要内容,如果未能解决你的问题,请参考以下文章

在 WPF 中对 DataGrid 进行预排序

如何在 WPF / MVVM 中对绑定到相同实例的两个列表视图进行不同选择

何时在 WPF 中对命令使用事件?

关于在 C# (WPF) 中对 COM 对象进行异步调用的问题

WPF中对datagrid删除选中的某一行。

基于单击列标题在WPF中对数据网格进行排序