如何将视图与视图模型或 ViewModel 的多个 DataTemplates 相关联? [英] How to associate view with viewmodel or multiple DataTemplates for ViewModel?
问题描述
鉴于我有一个 GridView,我想通过单击每个项目导航到不同的页面.
Given I have a GridView and I want to navigate to a different page by clicking each item.
如何导航到与视图模型关联的视图?
How can navigate to a view associated to the viewmodel?
在 WPF 中,有一种方法可以为视图模型设置多个数据模板.
In WPF there is a way to set multiple Datatemplates for the 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 中尝试的:
This is what I tried in UWP in my particular case:
<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 的值显示相应的视图.
The Frame is part of a page and I want to show the corresponding view based on the Value of the ViewModel.
Visual Studio 告诉我 DataTemplate 必须有一个 key 属性,但即便如此,它也不能像在 WPF 中那样工作,因为它没有创建视图.
Visual Studio tells me DataTemplate has to have a key attribute, but even then it doesn't work as it would in WPF, since it's not creating the view.
我知道 DataType 被替换为 x:DataType 并且 x:Type 似乎消失了.有没有办法达到类似的结果?
I know DataType was replaced with x:DataType and x:Type seems to be gone. Is there a way to achieve similar results?
推荐答案
在 WPF 中,DataType 是一个可以在运行时检索的依赖属性.
In WPF, the DataType is a dependency property which can be retrieved in runtime.
在 UWP 中,x:DataType 是编译时属性,您无法在运行时获取该值.
In UWP, the x:DataType is compile-time property, you cannot get the value in runtime.
我创建了一个关于如何通过 DataTemplateSelector 在 UWP 中映射数据类型和数据模板的简单演示.
I created a simple demo about how to map the datatype and data template in UWP through 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);
}
}
}
视图模型:
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>
这篇关于如何将视图与视图模型或 ViewModel 的多个 DataTemplates 相关联?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!