Пусть ViewModel знает универсальный объект View - PullRequest
0 голосов
/ 16 февраля 2012

У меня есть общий вид, в котором я «внедряю» какой-то конкретный вид в содержащийся ContentControl (я создал эту функцию с помощью этих справок -> help 1 - help 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 через «определенный» вид (клиент, продукт и т. Д.).

Ну. Это моя проблема:

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

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

1 Ответ

1 голос
/ 17 февраля 2012

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

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

EDIT:

В 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);
}

}

...