【问题标题】:How to use an object instantiated as a resource in XAML如何在 XAML 中使用实例化为资源的对象
【发布时间】:2020-11-25 01:03:09
【问题描述】:

我想在 XAML 中实例化一个用 C# 定义的类,并在 XAML 和代码中使用它。我发现我可以将对象实例化为资源并使用 TryFindResource("...") 在代码中定位它,但我对稍后在 XAML 中应该如何引用它感到困惑。例如,我有以下 XAML 代码:

<UserControl.Resources>
    <localx:PipeViewModel x:Key="pipeview" />
</UserControl.Resources>


<DockPanel  Grid.Row="0" Grid.RowSpan="3" Grid.ColumnSpan="3" Grid.Column="0" Background="White">
    <hx:HelixViewport3D x:Name="HelixViewport3D" 
                        ZoomExtentsWhenLoaded="True" 
                        CameraRotationMode="Trackball" 
                        CameraMode="FixedPosition"
                        PanGesture="LeftClick">
        <hx:DefaultLights  />
        <hx:DefaultLights  />
        <localx:PipeViewModel x:Name="pipeview" MyPipeModel="{Binding Path=PipeModel, RelativeSource={RelativeSource AncestorType=UserControl, AncestorLevel=1}}"/>
    </hx:HelixViewport3D>
</DockPanel>

我不确定资源部分中实例化的对象是否与插入 HelixVievPort3D 中的对象相同。我怀疑使用相同的名称并不一定意味着它们是相同的。如何在 HelixViewPort 中正确插入 pipeview 对象?

【问题讨论】:

  • 视图模型对象通常不会被添加到元素树中。您可以将其分配给视图元素的 DataContext 属性,以将其用作 Bindings 的来源。
  • 克莱门斯:感谢您的反馈。很抱歉,我并没有那么严格地遵循 MVVM。正如您可能从标签中所怀疑的那样,我的 ViewModel 对象结合了 View 和 ViewModel。它确实包含我想要将其插入视口的视觉元素。所以我的问题仍然悬而未决。
  • 听起来很糟糕。但是,请搜索 StackOverflow 以了解如何使用 StaticResourceExtension 来使用 UIElement 资源。

标签: wpf xaml


【解决方案1】:

确实,像这样声明元素会创建 实例。这称为Object element syntax。因此,资源部分中声明的PipeViewModel 与视口中的实例不同。

对象元素语法是 XAML 标记语法,它通过声明 XML 元素来实例化 CLR 类或结构。

在 XAML 中,您可以使用 StaticResourceDynamicResource 标记扩展来引用资源。两者的区别可以参考这个related question

您应该能够使用其中一种标记扩展作为标签来使用视口中的元素:

<hx:HelixViewport3D x:Name="HelixViewport3D" 
                    ZoomExtentsWhenLoaded="True" 
                    CameraRotationMode="Trackball" 
                    CameraMode="FixedPosition"
                    PanGesture="LeftClick">
   <hx:DefaultLights/>
   <hx:DefaultLights/>
   <StaticResource ResourceKey="pipeview"/>
</hx:HelixViewport3D>

由于您的资源中的实例现在是唯一的,您可能希望在其中添加绑定。

<UserControl.Resources>
    <localx:PipeViewModel x:Key="pipeview" MyPipeModel="{Binding Path=PipeModel, RelativeSource={RelativeSource AncestorType=UserControl}}"/>
</UserControl.Resources>

正如您对问题的评论,PipeViewModel 是视图模型和视图的混合体。我强烈建议您使用 MVVM 来明确分离视图、数据和业务逻辑,否则从长远来看,理解、扩展和维护您的应用程序会很困难。

【讨论】:

  • thatguy:非常感谢您的全面回复。是的,确实我的代码中的绑定已经完全符合您的建议。我会先完成我目前的设计,然后再遵循其他建议。
猜你喜欢
  • 1970-01-01
  • 2010-12-04
  • 1970-01-01
  • 2016-02-05
  • 2011-01-03
  • 1970-01-01
  • 1970-01-01
  • 2022-11-27
  • 1970-01-01
相关资源
最近更新 更多