Пусть ViewModel знает общий объект View

У меня есть общее представление, в котором я «внедряю» какое-то конкретное представление в содержащийся ContentControl (я создал эту функцию с помощью этой помощи -> help 1 - помощь 2).

Основной источник моих взглядов таков:

MyGenericView.xaml

<UserControl x:Class="MyNS.MyGenericView"
             ... >
    <UserControl.Resources>
        <vml:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
    </UserControl.Resources>
    <Grid DataContext="{Binding MyGenericViewModel, Source={StaticResource Locator}}">
        <ContentControl Content="{Binding MyObject}" />
    </Grid>
</UserControl>

CustomerView.xaml

<UserControl x:Class="AnotherNS.CustomerView"
             ... >
    <Grid>
        <StackPanel Orientation="Vertical">
            <Label Content="Description" />
            <TextBox Text="{Binding description}" />
        </StackPanel>
    </Grid>
</UserControl>

Crud.xaml: словарь ресурсов, который я использую, чтобы «решить», какое представление показывать, в зависимости от объекта DataType из MyObject, предоставляемого общим представлением.

<ResourceDictionary ... >
    <DataTemplate DataType="{x:Type mo:Customer}">
        <vw:CustomerView />
    </DataTemplate>
    <DataTemplate DataType="{x:Type mo:Product}">
        <vw:ProductView />
    </DataTemplate>
    ...
</ResourceDictionary>

Это работает нормально. Я могу управлять MyObject через "конкретное" представление (клиент, продукт и т. д.).

Что ж. Это моя проблема:

Все конкретные представления имеют свои собственные ViewModels и, конечно же, управляют данными соответствующих представлений. Но я не знаю (в модели представления), с каким объектом (MyObject) я работаю, потому что общее представление предоставляет его конкретному представлению, а не модели представления.

Есть ли способ сообщить ViewModels конкретных представлений об объекте, который "управляет" представлением?


person Diego Stiehl    schedule 16.02.2012    source источник


Ответы (1)


В MVVM Light вы должны отправить широковещательное сообщение в стиле издателя/подписчика, которое позволит вам взаимодействовать с моделью представления «хостинг» без необходимости иметь жесткую ссылку на элемент управления «хостинг» в элементе управления «размещенный».

Это позволяет «размещаемому» элементу управления оставаться отделенным от «размещенного» элемента управления и при этом взаимодействовать между ними.

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

В MVVM Light есть объект-мессенджер, который позаботится о многих деталях за вас. Вы можете создавать классы сообщений, которые хранят разные сообщения и отправляемые ими аргументы отдельно. Вы также можете указать «токен» только определенную строку (обычно я устанавливаю набор констант в классе для размещения своих различных «токенов»), который позволяет только подписчикам этого сообщения и этого токена получать сообщение. Я включил пример кода ниже того, что я использую в MVVM Light в v3 MVVM Light, вам нужно убедиться, что вы отменили регистрацию в сообщении, потому что оно не использует слабый шаблон обработки событий.

Если вы не хотите использовать MVVM Light, вы можете использовать ту же идею в своей модели издатель/подписчик, вам просто нужно будет выполнить работу по определению того, является ли токен, отправленный издателем, тем токеном, который подписчик ищет на вашем своя

public static class DescriptiveMessageName
{
public static void Send(object args)
{
    Messenger.Default.Send(args, "SpecificToken");
}

public static void Send(object args, string token)
{
    Messenger.Default.Send(args, token);
}

public static void Register(object recipient, Action<object> action)
{
    Messenger.Default.Register(recipient,
              "SpecificToken", action);
}

public static void Register(object recipient, string token, Action<object> action)
{
    Messenger.Default.Register(recipient,
              token, action);
}

public static void UnRegister(object recipient)
{
    Messenger.Default.Unregister<object>(recipient);
}

public static void UnRegister(object recipient, Action<object> action)
{
    Messenger.Default.Unregister<object>(recipient, action);
}

}

person Erick    schedule 16.02.2012
comment
Я уже думал об использовании метода издатель/подписчик. Не будут ли разные экземпляры путаться в правильном объекте? Можете ли вы обновить ответ, вставив в него пример? Большое спасибо. - person Diego Stiehl; 17.02.2012
comment
Что ж. Я уже использую MVVMLight в своем проекте. Я попытаюсь использовать этот объект мессенджера, который он предоставляет. Спасибо. - person Diego Stiehl; 19.02.2012