2

我在 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>

然后在使用 C++/CX 作为代码的文件“foo.xaml”中以下列方式使用此控件。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# 编写的相同组件时)?我猜这与组件互操作性有关。有没有人遇到过类似的问题?

任何意见,将不胜感激。

非常感谢。

4

1 回答 1

1

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

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

于 2013-03-07T19:28:39.440 回答