Связь между ViewModels - PullRequest
       28

Связь между ViewModels

1 голос
/ 28 сентября 2010

У меня есть два вопроса относительно связи между ViewModels.

Я занимаюсь разработкой программы управления клиентами. Я использую фреймворк Лорана Бюньона MVVM Light.

  1. На главной странице есть список клиентов. при щелчке каждого клиента появляется дочернее окно с информацией об этом клиенте. пользователь должен иметь возможность открывать несколько дочерних окон одновременно и сравнивать информацию между клиентами. как передать объект клиента из ViewModel главной страницы в ViewModel дочернего окна в режиме MVVM?

  2. В дочернем окне, которое показывает информацию о клиенте, есть несколько вкладок, каждая из которых отображает различные области информации. Я создал отдельные ViewModel для каждой из вкладок. как вы можете делиться информацией о текущем клиенте между моделями представления каждой вкладки?

Большое спасибо!

1 Ответ

0 голосов
/ 28 сентября 2010

В моем проекте я передаю ViewModels и дочерним окнам. Я создаю свойство зависимости для ViewModel в коде моего дочернего окна, и в установщике этого свойства я передаю ViewModel вместе с ViewModel моего дочернего окна. Это означает, что вы создаете отдельный класс ViewModel только для своего дочернего окна.

Чтобы ответить на ваш второй вопрос, вы могли бы, чтобы ViewModel вашего дочернего окна содержал свойства, о которых заботится каждая вкладка, но их контекст данных по-прежнему совпадает с контекстом данных дочернего окна, поэтому у них есть доступ к общим свойствам. На самом деле это очень просто, поскольку они автоматически получают контекст данных дочернего окна.

Вот пример, иллюстрирующий две концепции выше.

Дочернее представление окна DetailsWindow.xaml (обратите внимание, что у меня есть привычка называть мои дочерние представления окна * Window.xaml вместо * View.xaml)

<controls:ChildWindow x:Class="DetailsWindow"
                      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
                      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
                      xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
                      xmlns:Views="clr-namespace:Views"
                      Title="Details"
                      DataContext="{Binding DetailsWindowViewModel, Source={StaticResource Locator}}"
                      >
    <Grid>
        <sdk:TabControl>
            <sdk:TabItem Header="First Tab" Content="{Binding FirstTabContent}" />
            <sdk:TabItem Header="Second Tab" Content="{Binding SecondTabContent}" />
        </sdk:TabControl>
    </Grid>
</controls:ChildWindow>

Код представления дочернего окна DetailsWindow.xaml.cs и его интерфейс IDetailsWindow.cs

public partial class DetailsWindow : ChildWindow, IDetailsWindow
{
    private IDetailsWindowViewModel ViewModel
    {
        get { return this.DataContext as IDetailsWindowViewModel; }
    }

    public DetailsWindow()
    {
        InitializeComponent();
    }

    #region Customer dependency property

    public const string CustomerViewModelPropertyName = "Customer";

    public ICustomerViewModel Customer
    {
        get
        {
            return (ICustomerViewModel)GetValue(CustomerViewModelProperty);
        }
        set
        {
            SetValue(CustomerViewModelProperty, value);
            if (ViewModel != null)
            {
                ViewModel.Customer = value;
            }
        }
    }

    public static readonly DependencyProperty CustomerViewModelProperty = DependencyProperty.Register(
        CustomerViewModelPropertyName,
        typeof(ICustomerViewModel),
        typeof(CustomerDetailsWindow),
        null);

    #endregion
}

public interface IDetailsWindow
{
    ICustomerViewModel Customer { get; set; }
    void Show();
}

Модель представления дочернего окна DetailsWindowViewModel.cs и ее интерфейс IDetailsWindowViewModel

public class DetailsWindowViewModel : ViewModelBase, IDetailsWindowViewModel
{
    public DetailsWindowViewModel(IMessenger messenger)
        : base(messenger)
    {
    }

    #region Properties

    #region Customer Property

    public const string CustomerPropertyName = "Customer";

    private ICustomerViewModel _customer;

    public ICustomerViewModel Customer
    {
        get { return _customer; }
        set
        {
            if (_customer == value)
                return;

            var oldValue = _customer;
            _customer = value;
            RaisePropertyChanged(CustomerPropertyName, oldValue, value, true);
        }
    }

    #endregion

    #region FirstTabContent Property

    public const string FirstTabContentPropertyName = "FirstTabContent";

    private FrameworkElement _firstTabContent;

    public FrameworkElement FirstTabContent
    {
        get { return _firstTabContent; }
        set
        {
            if (_firstTabContent == value)
                return;

            _firstTabContent = value;
            RaisePropertyChanged(FirstTabContentPropertyName);
        }
    }

    #endregion

    #region SecondTabContent Property

    public const string SecondTabContentPropertyName = "SecondTabContent";

    private FrameworkElement _secondTabContent;

    public FrameworkElement SecondTabContent
    {
        get { return _secondTabContent; }
        set
        {
            if (_secondTabContent == value)
                return;

            _secondTabContent = value;
            RaisePropertyChanged(SecondTabContentPropertyName);
        }
    }

    #endregion

    #endregion
}

public interface IDetailsWindowViewModel
{
    ICustomerViewModel Customer { get; set; }
    FrameworkElement FirstTabContent { get; set; }
    FrameworkElement SecondTabContent { get; set; }

    void Cleanup();
}

И вы можете показать дочернее окно из вашего MainPageViewModel.cs следующим образом.

public class MainViewModel : ViewModelBase, IMainViewModel
{
    private readonly IDetailsWindow _detailsWindow;

    public MainViewModel(IMessenger messenger, IDetailsWindow DetailsWindow)
        : base(messenger)
    {
        _detailsWindow = DetailsWindow;
    }

    private void DisplayCustomerDetails(ICustomerViewModel customerToDisplay)
    {
        _detailsWindow.Customer = customerToDisplay;
        _detailsWindow.Show();
    }
}

Обратите внимание, что я создаю интерфейсы для всех моих моделей представления и дочерних окон, и я использую контейнер DI / IoC в моем ViewModelLocator, чтобы все зависимости моих ViewModels вводились для меня. Тебе не обязательно это делать, но мне нравится, как это работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...