2015-10-21 1 views
9

Учитывая, что у меня есть GridView, и я хочу перейти на другую страницу, щелкнув каждый элемент.Как связать представление с помощью viewmodel или нескольких DataTemplates для ViewModel?

Как перейти к представлению, связанному с viewmodel?

В WPF существует способ установить несколько Datatemplates для viewmodel.

<TabControl Grid.Row="1" Margin="0" ItemsSource="{Binding Tabs}" SelectedIndex="0" SelectedItem="{Binding SelectedTab}"> 
    <TabControl.Resources> 
     <DataTemplate DataType="{x:Type dashboard:DashboardViewModel}"> 
      <dashboard:DashboardView/> 
     </DataTemplate> 
     <DataTemplate DataType="{x:Type controls:ExchangeViewModel}"> 
      <controls:ExchangeView/> 
     </DataTemplate> 
     <DataTemplate DataType="{x:Type request:RequestViewModel}"> 
      <request:RequestView/> 
     </DataTemplate> 
     <DataTemplate DataType="{x:Type addresses:AddressViewModel}"> 
      <addresses:AddressView/> 
     </DataTemplate> 
     <DataTemplate DataType="{x:Type settings:ExchangeSettingsViewModel}"> 
      <settings:ExchangeSettingsView/> 
     </DataTemplate> 

    </TabControl.Resources> 
    <TabControl.ItemTemplate> 
     <DataTemplate DataType="vm:ViewModelBase"> 
      <TextBlock Text="{Binding Header}" FontSize="14"></TextBlock> 
     </DataTemplate> 
    </TabControl.ItemTemplate> 
</TabControl> 

Это то, что я пытался в UWP в моем конкретном случае:

<Frame Grid.Row="1" DataContext="{x:Bind ViewModel.Value}"> 
    <Frame.Resources> 
     <DataTemplate x:DataType="viewModels:ExampleViewModel1"> 
      <views:ExampleView1></views:ExampleView1> 
     </DataTemplate> 
     <DataTemplate x:DataType="viewModels:ExampleViewModel2"> 
      <views:ExampleView2></views:ExampleView2> 
     </DataTemplate> 
    </Frame.Resources> 
</Frame> 

Фрейм является частью страницы, и я хочу, чтобы показать соответствующее представление, основанное на значении в ViewModel.

Visual Studio сообщает, что DataTemplate должен иметь ключевой атрибут, но даже тогда он не работает так, как в WPF, поскольку он не создает представление.

Я знаю, что DataType был заменен на x: DataType и x: Тип кажется ушедшим. Есть ли способ добиться аналогичных результатов?

+1

Рассматривали ли вы с помощью 'ContentPresent er' для отображения вашей модели просмотра? –

+0

Я собираюсь добавить дополнительную информацию о сатите, который у меня есть в UWP, потому что TabControl - пример. – Andre

+0

Существует поток на UserVoice для этой [link] (https://wpdev.uservoice.com/forums/110705-universal-windows-platform/suggestions/18575131-add-implicit-datatemplates-to-uwp) – Portikus

ответ

13

В WPF, DataType - это свойство зависимостей, которое можно получить во время выполнения.

В UWP x: DataType является свойством времени компиляции, вы не можете получить значение во время выполнения.

Я создал простую демонстрацию о том, как сопоставить тип данных и шаблон данных в UWP через DataTemplateSelector.

DataTemplateSelector:

namespace UWPApp 
{ 
    public class Template 
    { 
     public string DataType { get; set; } 

     public DataTemplate DataTemplate { get; set; } 
    } 

    public class TemplateCollection2 : System.Collections.ObjectModel.Collection<Template> 
    { 
    } 


    public class MyDataTemplateSelector : DataTemplateSelector 
    { 
     public TemplateCollection2 Templates { get; set; } 

     private IList<Template> _templateCache { get; set; } 

     public MyDataTemplateSelector() 
     { 

     } 

     private void InitTemplateCollection() 
     { 
      _templateCache = Templates.ToList(); 
     } 

     protected override DataTemplate SelectTemplateCore(object item, DependencyObject container) 
     { 
      if (_templateCache == null) 
      { 
       InitTemplateCollection(); 
      } 

      if(item != null) 
      { 
       var dataType = item.GetType().ToString(); 

       var match = _templateCache.Where(m => m.DataType == dataType).FirstOrDefault(); 

       if(match != null) 
       { 
        return match.DataTemplate; 
       } 
      } 

      return base.SelectTemplateCore(item, container); 
     } 
    } 
} 

ViewModel:

namespace UWPApp 
{ 
    public class ViewModel1 
    { 
     public string Text1 { get; set; } 
    } 

    public class ViewModel2 
    { 
     public string Text2 { get; set; } 
    } 
} 

XAML:

<Grid 
    x:Name="container" 
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> 
    <Grid.Resources> 
     <local:TemplateCollection2 x:Key="templates"> 
      <local:Template DataType="UWPApp.ViewModel1"> 
       <local:Template.DataTemplate> 
        <DataTemplate x:DataType="local:ViewModel1"> 
         <StackPanel> 
          <TextBlock Text="{Binding Text1}"></TextBlock> 
          <TextBlock Text="From template1"></TextBlock> 
         </StackPanel> 
        </DataTemplate> 
       </local:Template.DataTemplate> 
      </local:Template> 
      <local:Template DataType="UWPApp.ViewModel2"> 
       <local:Template.DataTemplate> 
        <DataTemplate x:DataType="local:ViewModel2"> 
         <StackPanel> 
          <TextBlock Text="{Binding Text2}"></TextBlock> 
          <TextBlock Text="From template2"></TextBlock> 
         </StackPanel> 
        </DataTemplate> 
       </local:Template.DataTemplate> 
      </local:Template> 
     </local:TemplateCollection2> 
     <local:MyDataTemplateSelector 
     x:Key="myDataTemplateSelector" Templates="{StaticResource templates}"> 
     </local:MyDataTemplateSelector> 
    </Grid.Resources> 
    <StackPanel> 
     <Button x:Name="button" Click="button_Click">Click Me</Button> 
     <ContentControl x:Name="stage" ContentTemplateSelector="{StaticResource myDataTemplateSelector}"> 

     </ContentControl> 
    </StackPanel> 
</Grid> 
+0

Many Thanks , Это действительно лаваш, чтобы сделать эту работу. –

+2

Хотя я одобрил ответ, так как он решает проблему, это невероятно, так как в принципе такая простая вещь нуждается в тоннах дополнительного кода. Иногда Microsoft заставляет задуматься, насколько они счастливы с этой платформой. Это беспорядок. :( –

Смежные вопросы