отправить параметр из view-модели в конструктор другой view-модели vol.2 - PullRequest
2 голосов
/ 16 декабря 2010

Я пытаюсь реализовать аванс в форме моего вопроса здесь: отправить параметр из модели представления в конструктор другой модели представления .

У меня есть одна модель вида оболочки и 2 модели вида. Мне нужно передать объект из одной модели представления в другую модель представления (конструктор.)

Модели моего вида выглядят так:

LogOnViewModel:

public interface ILogOnViewModel : IScreen, IDataErrorInfo
{
    string Nick { get; set; }
    string Password { get; set; }
    bool CanLogOn { get; set; }
    void LogOn(string nick, string password);
}


public class LogOnViewModel : Screen,ILogOnViewModel
{

    //[Import]
    //private IShellViewModel _shellViewModel;
}

MessangerViewModel:

 public interface  IMessengerViewModel:IScreen
    {
        BitmapImage AvatarImage { get; set; }
        string AvatarStatus { get; set; }
        KeyValuePair<string, Friend> SelectedFriend { get; set; }
    }

    public class MessengerViewModel : Screen,IMessengerViewModel
    {
    }

В модели оболочек я пытаюсь создать абстрактную фабрику для моделей представлений.

ShellViewModel:

 public interface IFactory
    {
        ILogOnViewModel CreateLogOnViewModel();
        IMessengerViewModel CreateMessengerViewModel();
    }

    public class ConcreteFactory : IFactory
    {
        #region Implementation of IFactory

        public ILogOnViewModel CreateLogOnViewModel()
        {
            return new LogOnViewModel();
        }

        public IMessengerViewModel CreateMessengerViewModel()
        {
            return new MessengerViewModel();
        }

        #endregion
    }


    public interface IShellViewModel
    {
        void ShowLogOnView();
        void ShowMessengerView();
    }

    [Export(typeof(IShellViewModel))]
    public class ShellViewModel : Conductor<IScreen>, IShellViewModel
    {
        private ConcreteFactory _factory;

        public ShellViewModel()
        {
            _factory=new ConcreteFactory();
            ShowLogOnView();
        }

        public void ShowLogOnView()
        {
            ActivateItem(_factory.CreateLogOnViewModel());
            //ActivateItem(IoC.Get<LogOnViewModel>());
        }

        public void ShowMessengerView()
        {
            ActivateItem(_factory.CreateMessengerViewModel());
            //ActivateItem(IoC.Get<MessengerViewModel>());
        }
    }

Моя проблема: как я могу вызвать метод из Shell-view-model в LogOnVieModel. Я получаю заранее, что плохо использовать IoC и импортировать атрибут на входной shell-view-model в другое представление. Предположительно, лучше использовать обработчик событий по этому вопросу. Но я не знаю, как использовать этот класс в моей проблеме.

Я думаю, опубликовать метод из shell-view-model и обработать в logon-view-model.

Но я думаю, что все, что я делаю сейчас, плохо.

1 Ответ

0 голосов
/ 16 декабря 2010

Вам нужно немного изменить свой код. Для начала я думаю, что лучше всего отделить вашу реализацию IFactory (и переименовать ее во что-нибудь менее общее), например ::

public interface IViewModelFactory
{
  ILogOnViewModel CreateLogOnViewModel(IShellViewModel shellViewModel);
}

(я опустил часть вашего кода). Затем убедитесь, что вы Export ваш ConcreteFactory (и снова, переименуйте). Мы заставляем фабричный метод взять экземпляр вашего IShellViewModel контракта.

[Export(typeof(IViewModelFactory))]
public class DefaultViewModelFactory : IViewModelFactory
{
  public ILogOnViewModel CreateLogOnViewModel(IShellViewModel shellViewModel)
  {
    return new LogOnViewModel(shellViewModel);
  }
}

И настройте LogOnViewModel так, чтобы в этом случае IShellViewModel передавался с завода.

public class LogOnViewModel : ILogOnViewModel
{
  private readonly IShellViewModel _shellViewModel;

  public LogOnViewModel(IShellViewModel shellViewModel)
  {
    _shellViewModel = shellViewModel;
  }

  public void SomeOperation()
  {
    // Do work with _shellViewModel;
  }
}

Далее, мы изменим ShellViewModel, чтобы он был построен, и зависимость была введена для фабрики, которую он будет использовать:

[Export(typeof(IShellViewModel))]
public class ShellViewModel : Conductor<IScreen>, IShellViewModel
{
  private readonly IViewModelFactory _factory;

  [ImportingConstructor]
  public ShellViewModel(IViewModelFactory factory)
  {
    _factory = factory;
  }

  public void ShowLogOnView()
  {
    var model = _factory.CreateLogOnViewModel(this);
    ActivateItem(model);
  }
}

ImportingConstructor предписывает MEF использовать этот конструктор и вводить соответствующие типы.

Надеюсь, это указывает на правильное направление?

...