Нарушение привязки с подходом Prism, Silverlight и ViewFirst

Проблема, с которой мы сталкиваемся, заключается в том, что мы не можем заставить работать привязку в нашем приложении prism silverlight при использовании подхода, основанного на модели представления. Первый подход к просмотру работает нормально. Мы просмотрели официальную документацию и различные веб-сайты, но все еще не решили проблему. Ниже приведен код как для модели представления, так и для подхода, основанного на представлении. Мы что-то упускаем? Читайте об этом в моем блоге http://silvercasts.blogspot.com

Первый подход к представлению модели:

Загрузчик:

   internal void RegisterLoginRegionAndView()
   {
       IRegionManager regionManager = Container.Resolve<IRegionManager>();

       regionManager.RegisterViewWithRegion(ShellRegionNames.MainRegion,
       () => Container.Resolve<IViewModel>().View);
    }

ViewModel:

   public ViewModel(IView view)
   {
       View = view;
       View.SetModel(this);

       User = new User();
       User.Username = "TestUser";
   }

ViewModel Интерфейс:

 public interface IViewModel
   {
       IView View { get; set; }
   }

Просмотр интерфейса:

public interface IView
   {
       void SetModel(IViewModel model);
   }

Просмотреть Xaml:

 <TextBox x:Name="Username" TextWrapping="Wrap" Text="{Binding User.Username}" />

Просмотреть код позади:

public void SetModel(IViewModel viewModel)
   {
       this.DataContext = viewModel;
   }

Посмотреть первый подход

Загрузчик:

regionManager.RegisterViewWithRegion(ShellRegionNames.MainRegion, typeof(IView));

ViewModel:

  public ViewModel()
   {
       User = new User();
       User.Username = "TestUser";
   }

Просмотреть код позади:

public View(IViewModel viewModel)
   {
       InitializeComponent();
       this.DataContext = viewModel;
   }

person cmaduro    schedule 23.09.2009    source источник


Ответы (3)


Ваша реализация SetModel в вашем представлении должна быть следующей:

public void MyUserControl : UserControl, IView
{
     //...
     public void SetModel(IViewModel vm)
     {
          this.DataContext = vm;
     }
}

Если этого нет, значит, это должно быть (вы не опубликовали свою реализацию SetModel, но в этом случае это может быть источником проблемы).

Если проблема не в этом, скорее всего, ваша ViewModel не реализует INotifyPropertyChanged. Обычно я использую базовую модель ViewModel, которая делает следующее:

public class ViewModelBase : INotifyPropertyChanged
{
     public event PropertyChangedEventHandler PropertyChanged;
     public void OnPropertyChanged(string propertyName)
     {
          if(PropertyChanged != null)
          {
               PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
          }
     }
}

И все мои ViewModels вытекают из этого:

public class MyViewModel : ViewModelBase
{
     private User _user;
     public User User
     {
         get { return _user; }
         set
         {
              _user = value;
              OnPropertyChanged("User");
         }
     }
}

Примечание. в вашем случае объект «Пользователь», вероятно, также должен быть ViewModel и также вызывать OnPropertyChanged для свойства Username.

Надеюсь это поможет.

person Anderson Imes    schedule 23.09.2009
comment
Я сделал, но форматирование испортилось. Это прямо под кодом XAML. Но, судя по всему, выглядит неплохо. Спасибо! - person cmaduro; 24.09.2009

Для меня очевидная разница в том, что вы устанавливаете DataContext в подходе «сначала просмотр», а не в подходе «сначала представьте модель». Я не уверен, что Prism устанавливает для вас DataContext (я предполагаю, что вы предполагаете, что это так), но попробуйте установить DataContext вручную, чтобы увидеть, не в этом ли проблема. В конструкторе ViewModel вы вызываете View.SetModel (this) - устанавливает ли этот вызов DataContext?

person James Cadd    schedule 23.09.2009

Проблема заключалась в том, что я использовал метод SetModel до создания экземпляра объекта данных. Перемещаем его так:



       public ViewModel(IView view)
       {
           View = view;

           User = new User();
           User.Username = "TestUser";

           View.SetModel(this);
       }

решил проблему.

person cmaduro    schedule 24.09.2009
comment
Это вызвало проблему, потому что ваша ViewModel, по-видимому, неправильно реализует INotifyPropertyChanged. Это не должно быть проблемой. Я дополню свой ответ некоторым дополнительным словоблудием по этому поводу. - person Anderson Imes; 24.09.2009