Некоторое время я использовал MVVM Light, поэтому у меня есть небольшой опыт, однако я никогда не пробовал делать несколько экземпляров одной и той же viewmodel
В принципе, я создал viewmodel
usercontrol
которого есть viewmodel
и я использую 4 экземпляра этого элемента управления в окне WPF.
Вот как я делаю привязку в xaml, довольно простой материал.
<UserControl.DataContext>
<Binding Path="PodView" Source="{StaticResource Locator}"/>
</UserControl.DataContext>
<TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" Margin="6,0,0,0" Text="{Binding PodModel}"/>
Вот код локатора службы.
public class ViewModelLocator
{
/// <summary>
/// Initializes a new instance of the ViewModelLocator class.
/// </summary>
public ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc.Default.Register<MainViewModel>();
SimpleIoc.Default.Register<PODViewModel>();
}
public MainViewModel Main
{
get
{
return ServiceLocator.Current.GetInstance<MainViewModel>();
}
}
public PODViewModel PodView
{
get
{
//return ServiceLocator.Current.GetInstance<PODViewModel>(Guid.NewGuid().ToString());
return new PODViewModel();
}
}
public static void Cleanup()
{
// TODO Clear the ViewModels
}
}
Как вы можете видеть, я попробовал несколько способов вернуть экземпляр viewmodel, но я не думаю, что проблема там.
Хорошо, так что теперь на вопрос. В viewmodel
меня есть свойство, подобное этому, которое связано с viewmodel
private string _PodModel;
public string PodModel
{
get { return _PodModel; }
set
{
if (_PodModel != value)
{
_PodModel = value;
RaisePropertyChanged(() => PodModel);
}
}
}
Теперь в конструкторе у меня есть это, что отлично работает, и я проверяю это как в blend, так и при запуске программы.
public PODViewModel()
{
if (IsInDesignMode)
{
//// // Code runs in Blend --> create design time data.
PodModel = "HSA3"; // <-- This works fine
}
else
{
//// // Code runs "for real"
PodModel = "Fred"; // <-- This works fine
}
}
Теперь проблема в том, что каждый элемент управления имеет поток для выполнения длинной задачи и изменяет свойство PodModel
. При этом я не получаю никаких исключений, но пользовательский интерфейс не обновляется.
PodModel = "blah blah blah";
Поэтому я переместил код в поток пользовательского интерфейса так, но пользовательский интерфейс все равно не будет обновляться.
DispatcherHelper.CheckBeginInvokeOnUI(() =>
{
PodModel = "blah blah blah";
});
Я поставил точку останова на свойство set, и я вижу, что свойство действительно меняется.
Любые идеи, почему пользовательский интерфейс не будет обновляться?
Обновление 1: я заметил, что есть 2 вызова для получения экземпляра PodViewModel
Я думаю, что проблема в том, что свойство PodView всегда возвращает новый объект. Это приводит к ситуации, когда обновляется другой экземпляр модели представления (например, устанавливая свойство PodModel в "бла-бла-бла"), чем привязан к пользовательскому интерфейсу. Он не может работать, потому что пользовательский интерфейс не знает, что его экземпляр модели просмотра был обновлен. Чтобы подтвердить это, попробуйте использовать следующий код:
private PODViewModel _podView = new PODViewModel();
public PODViewModel PodView
{
get
{
return _podView ;
}
}