【问题标题】:Consuming C# component from C++/CX and C#从 C++/CX 和 C# 使用 C# 组件
【发布时间】:2013-02-20 17:19:23
【问题描述】:

我在 C++/CX 中创建了一个简单的控件 SimpleControl.xaml,定义为:

<UserControl ..  > // Attributes omitted for reading simplicity
<Grid>

 <Grid.RowDefinitions>
    <RowDefinition Height="40"/>
    <RowDefinition Height="30"/>
 <RowDefinition Height="30"/>
 </Grid.RowDefinitions>

 <Grid.ColumnDefinitions>
    <ColumnDefinition Width="100"/>
    <ColumnDefinition Width="*"/>
 </Grid.ColumnDefinitions>

    <Image x:Name="PersonaPicture" ... />
    <Border x:Name="PhotoTextBackdrop" ... />
    <TextBlock x:Name="PersonaName" .../>

</Grid>
</UserControl>

然后这个控件在一个文件“foo.xaml”中以如下方式使用,该文件使用C++/CX作为后面的代码。 SuperPanel 继承自 Windows.UI.Xaml.Controls.Panel 并在 TastyLib 组件中定义(由该 C++/CX 组件使用)。 'fruity' 命名空间指向 TastyLib。 TastyLib 组件是用 C# 编码的:

</fruity:SuperPanel>
    <local:SimpleControl x:Name="gPerson1" Grid.Row="0" Grid.Column="0" />
    <Rectangle Fill="SaddleBrown" Height="50" Width="50" Grid.Row="1" Grid.Column="0" />
    <UserControl Grid.Row="2" Grid.Column="0" />
</fruity:SuperPanel>

设置断点并查看手表,我观察到以下是面板的孩子:

child[0] 是 Windows.UI.Xaml.UIElement,child[1] 是 Windows.UI.Xaml.Shapes.Rectangle 和 child[2] 是 Windows.UI.Xaml.Controls.UserControl

现在,在手表中,我期待第一个孩子是 SimpleControl,但实际上它是 UIElement,这让我感到惊讶。那个是从哪里来的?为什么它将 SimpleControl 的祖先显示为 child[0] 而它仍然可以将 UserControl 识别为 child[2] ?

我在使用 TastyLib 的 C# 组件中重新创建了另一个 SimpleControl(所以这个 SimpleControl 也是用 C# 编写的,并且没有使用 C++/CX),并将该控件放在另一个 SuperPanel 中,就像第一种情况一样(但都是在 C#这次)。在设置相同的断点并在监视窗口中查看时,我看到 child[0] 是我所期望的 - 一个 SimpleControl。在这种情况下:

child[0] 是 FooProject.SimpleControl,child[1] 是 Windows.UI.Xaml.Shapes.Rectangle,child[2] 是 Windows.UI.Xaml.Controls.UserControl

造成这种二分法的根本原因是什么?用 C++/CX 编写的控件不应该与用 C# 编写的控件完全相同(当使用用 C# 编写的相同组件时)?我猜这与组件互操作性有关。有没有人遇到过类似的问题?

任何建议将不胜感激。

非常感谢。

【问题讨论】:

  • 这听起来更像是你对逻辑对象树和可视对象树之间的区别感到困惑......

标签: c# interop c++-cx


【解决方案1】:

根据我所做的研究,问题是在用 C++/CX 编写的控件的情况下跨越了 winRT 边界,因此当 CLR 请求类型时,对象返回 Windows.UI.Xaml。来自其 GetRuntimeClassName 实现的 UIElement(为什么?)。

在使用 C# 开发的控件的情况下,不会越过 winRT 边界,并且 .NET 对象正在与另一个 .NET 对象通信,因此类型是已知的。

【讨论】:

    猜你喜欢
    • 2014-02-20
    • 1970-01-01
    • 2016-01-29
    • 2015-10-25
    • 2017-11-17
    • 2013-06-16
    • 2012-01-13
    • 1970-01-01
    • 2015-06-19
    相关资源
    最近更新 更多