Bagaimana cara mengaitkan tampilan dengan viewmodel atau beberapa DataTemplates untuk ViewModel?

Mengingat saya memiliki GridView dan saya ingin menavigasi ke halaman lain dengan mengklik setiap item.

Bagaimana cara menavigasi ke tampilan yang terkait dengan model tampilan?

Di WPF ada cara untuk mengatur beberapa templat Data untuk model tampilan.

<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>

Inilah yang saya coba di UWP dalam kasus khusus saya:

<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>

Bingkai adalah bagian dari halaman dan saya ingin menampilkan tampilan yang sesuai berdasarkan Nilai ViewModel.

Visual Studio memberi tahu saya bahwa DataTemplate harus memiliki atribut kunci, tetapi meskipun demikian itu tidak berfungsi seperti di WPF, karena tidak membuat tampilan.

Saya tahu DataType diganti dengan x:DataType dan x:Type sepertinya hilang. Apakah ada cara untuk mencapai hasil serupa?


person Andre    schedule 21.10.2015    source sumber
comment
Sudahkah Anda mempertimbangkan untuk menggunakan ContentPresenter untuk menampilkan Model Tampilan Anda?   -  person Mike Eason    schedule 21.10.2015
comment
Saya akan menambahkan lebih banyak informasi tentang situasi yang saya alami di UWP, karena TabControl hanyalah contoh saja.   -  person Andre    schedule 21.10.2015
comment
Ada thread di UserVoice untuk tautan   -  person Portikus    schedule 09.05.2017


Jawaban (1)


Di WPF, DataType adalah properti ketergantungan yang dapat diambil saat runtime.

Di UWP, x:DataType adalah properti waktu kompilasi, Anda tidak bisa mendapatkan nilainya saat runtime.

Saya membuat demo sederhana tentang cara memetakan tipe data dan template data di UWP melalui 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);
        }
    }
}

Model Tampilan:

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>
person Jeffrey Chen    schedule 23.10.2015