0

在我的 WPF 应用程序中,我有MainWindow控件,并且GraphControl用户控件通过 XAML 标记放置在 Window 内。GraphControl已分配GraphControlViewModel,并且它包含附件GraphView控件(从Control类派生)。该类型的实现大纲(简化)如下:

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
}

节点视图模型.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 上的数据模板概述文档中所述:

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?

4

2 回答 2

1

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

<GraphUI:GraphView NodesSource="{Binding Graph.Nodes}" 
                   DataTemplate={StaticResource NodeViewModelKey}/>
于 2013-09-18T15:13:35.393 回答
1

如果你GraphView喜欢你的名字:

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

在用户控件背后的代码中,您可以执行以下操作:

      myGraph.Resources.Add(
      new DataTemplateKey(typeof(NodeViewModel)), 
      Resources["NodeViewModelKey"]);
于 2013-09-18T15:22:18.960 回答