首页 文章

如何以编程方式将DataTemplate应用于View Model类

提问于
浏览
0

在我的WPF应用程序中,我有 MainWindow 控件,并且 GraphControl 用户控件放在Window中的XAML标记 . GraphControl 已分配 GraphControlViewModel ,它包含附件 GraphView control(派生自 Control class) . 这些类型的实现的概要(简化)如下:

GraphControl.xaml

<UserControl
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:designer="clr-namespace:Designer"
  xmlns:GraphUI="clr-namespace:GraphUI;assembly=GraphUI"
  xmlns:GraphModel="clr-namespace:GraphModel;assembly=GraphModel">

  /* simplified document content */

  <UserControl.Resources>

    <ResourceDictionary>

      <DataTemplate DataType="{x:Type GraphModel:NodeViewModel}">

          /* data template definition here*/

      </DataTemplate>

    </ResourceDictionary>

  </UserControl.Resources>

  <UserControl.DataContext>
    <designer:GraphControlViewModel />
  </UserControl.DataContext>

  <DockPanel>

    <GraphUI:GraphView NodesSource="{Binding Graph.Nodes}" />

  </DockPanel>

</UserControl>

GraphControlViewModel.cs:

public class GraphControlViewModel : AbstractModelBase
{
    private GraphViewModel graph;

    public GraphViewModel Graph
    {
        get
        {
            return this.graph;
        }
        set
        {
            this.graph = value;

            this.OnPropertyChanged("Graph");
        }
    }

    // implementation here
}

GraphViewModel.cs:

public sealed class GraphViewModel
{
    private ImpObservableCollection<NodeViewModel> nodes;

    public ImpObservableCollection<NodeViewModel> Nodes
    {
        get
        {
            return this.nodes ?? ( this.nodes = new ImpObservableCollection<NodeViewModel>() );
        }
    }

    // implementation here
}

NodeViewModel.cs:

public sealed class NodeViewModel : AbstractModelBase
{
   // implementation here
}

GraphView.cs:

public partial class GraphView : Control
{
    // implementation of display details here

    public IEnumerable NodesSource
    {
        get
        {
            return (IEnumerable)this.GetValue(NodesSourceProperty);
        }
        set
        {
            this.SetValue(NodesSourceProperty, value);
        }
    }
}

应用程序工作和外观发明, DataTemplate 正确应用于View Model类 .

但是,此时,为了便于访问,需要将 x:key 属性添加到 DataTemplate 定义:

<DataTemplate x:Key="NodeViewModelKey" DataType="{x:Type GraphModel:NodeViewModel}">

    /* data template definition here*/

</DataTemplate>

在这里我的问题发生了 . 正如在MSDN上的Data Templating Overview文档中所述:

If you assign this DataTemplate an x:Key value, you are overriding the implicit x:Key and the DataTemplate would not be applied automatically.

实际上,在我添加 x:Key 属性后, DataTemplate 未应用于我的View Model类 .

如何在我的情况下以编程方式应用DataTemplate?

2 回答

  • 1

    如果你将 GraphView 命名为:

    <GraphUI:GraphView x:Name="myGraph" NodesSource="{Binding Graph.Nodes}" />
    

    在您的usercontrol背后的代码中,您可以执行以下操作:

    myGraph.Resources.Add(
          new DataTemplateKey(typeof(NodeViewModel)), 
          Resources["NodeViewModelKey"]);
    
  • 1

    我会尝试将 DataTemplate 依赖属性添加到 GraphView ,然后尝试使用它像这样:

    <GraphUI:GraphView NodesSource="{Binding Graph.Nodes}" 
                       DataTemplate={StaticResource NodeViewModelKey}/>
    

相关问题