Как лучше всего переключать представления / пользовательские элементы управления в MVVM-light и WPF?

Вы не можете сделать это без отражения. Однако вы можете делать это с отражением. Вот полный пример:

using System;
using System.Reflection;

public class Generic<T>
{
    public Generic()
    {
        Console.WriteLine("T={0}", typeof(T));
    }
}

class Test
{
    static void Main()
    {
        string typeName = "System.String";
        Type typeArgument = Type.GetType(typeName);

        Type genericClass = typeof(Generic<>);
        // MakeGenericType is badly named
        Type constructedClass = genericClass.MakeGenericType(typeArgument);

        object created = Activator.CreateInstance(constructedClass);
    }
}

Примечание: если ваш универсальный класс принимает несколько типов, вы должны включать запятые, когда вы опускаете имена типов, например:

Type genericClass = typeof(IReadOnlyDictionary<,>);
Type constructedClass = genericClass.MakeGenericType(typeArgument1, typeArgument2);
24
задан JReed 24 May 2011 в 17:34
поделиться

1 ответ

Вы бы сделали это в родительской ViewModel.

Например, если ваша страница (назовите ее PageViewModel) имела два вида (ViewModelA и ViewModelB), у вас будет свойство на PageViewModel с именем CurrentView, и это будет определять, какой вид является видимый. Когда PageViewModel.CurrentView установлен на экземпляр ViewModelA, тогда DataTemplate ViewA используется для рисования контента. Когда он установлен на экземпляр ViewModelB, отображается DataTemplate ViewB.

<DataTemplate DataType="{x:Type local:PageViewModel}">
    <ContentControl Content="{Binding CurrentView}" />
</DataTemplate>

<DataTemplate DataType="{x:Type local:ViewModelA}">
    <TextBlock Text="I'm ViewModelA" />
</DataTemplate>

<DataTemplate DataType="{x:Type local:ViewModelB}">
    <TextBlock Text="I'm ViewModelB" />
</DataTemplate>

Было бы идеально вызывать команду переключения представлений из родительского представления (в данном случае DataTemplate для PageViewModel), однако, если вы хотите переключить представления из ViewModelA / B, вы можете либо подключить поднимите событие вручную, когда объекты будут созданы (CurrentView.ChangeViewCommand = this.ChangeViewCommand), или загляните в систему обмена сообщениями. MVVM Light имеет простой Messenger класс, который, как я обнаружил, довольно прост в использовании, или Prism имеет более продвинутый EventAggregator

. Если вы хотите переключить виды для одной и той же ViewModel, я бы порекомендовал свойство Mode. который используется, чтобы определить, какой вид использовать. Например:

<DataTemplate x:Key="ViewA" DataType="{x:Type local:MyViewModel}">
    <TextBlock Text="I'm ViewModelA" />
</DataTemplate>

<DataTemplate x:Key="ViewB" DataType="{x:Type local:MyViewModel}">
    <TextBlock Text="I'm ViewModelB" />
</DataTemplate>

<DataTemplate DataType="{x:Type local:MyViewModel}">
    <ContentControl Content="{Binding }">
        <ContentControl.Style>
            <Style TargetType="{x:Type ContentControl}">
                <Setter Property="ContentTemplate" Value="{StaticResource ViewA}" />
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Mode}" Value="2">
                        <Setter Property="ContentTemplate" Value="{StaticResource ViewB}" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </ContentControl.Style>
    </ContentControl>
</DataTemplate>

РЕДАКТИРОВАТЬ

Я на самом деле вижу, что такого рода вопросы часто возникают, поэтому разместил что-то об этом здесь , если всем интересно

34
ответ дан acidbabies 24 May 2011 в 17:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: