2013-09-18 2 views
0

В моем приложении WPF у меня есть элемент управления MainWindow и GraphControl пользовательский элемент управления, размещенный внутри окна с помощью разметки XAML. GraphControl присвоил GraphControlViewModel, и он содержит аксессуар GraphView управление (производное от Control класс). Контур (упрощенный) реализаций, что типы имеет следующий вид:Как программно применять DataTemplate для просмотра класса модели

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 правильно применяется для просмотра класса модели.

Однако, на данный момент, есть нужно добавить x:key атрибут DataTemplate определения для целей доступности:

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

    /* data template definition here*/ 

</DataTemplate> 

А вот моя проблема возникает. Как указано в Data Templating Overview документации на 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 в моем случае?

+0

@Omribitan, правда? Это противоположность лучшей практике MVVM. Модель не должна отображаться непосредственно в пользовательском интерфейсе - для этого предназначена ViewModel. –

+0

@MarkGreen ВЫ ПРАВИЛЬНО! запутался, взял его обратно :) –

ответ

1

Если вы назвали ваш GraphView как:

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

В кода вашего пользовательского управления вы можете сделать:

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

Я хотел бы попробовать добавить свойство в DataTemplate зависимость к GraphView, а затем попытаться использовать это что-то вроде этого:

<GraphUI:GraphView NodesSource="{Binding Graph.Nodes}" 
        DataTemplate={StaticResource NodeViewModelKey}/> 
Смежные вопросы