我有一个viewmodel ProductionViewModel
,它扩展了更为一般的EntityViewModelBase<T>
,它再次扩展了mmvm-light的ViewModelBase
(源自ObservableObject)。
调用此viewmodel时,我通过它的方法SetItem(production)
设置基础数据
ProductionViewModel pview = ServiceLocator.Current.GetInstance<ProductionViewModel>();
pview.SetItem((Models.Production) msg.Model);
ViewContent = pview;
相关的XAML:
<DataTemplate x:Name="ProductionViewTemplate" DataType="{x:Type viewmodels:ProductionViewModel}">
<views:ProductionView DataContext="{Binding}"/>
</DataTemplate>
<!-- then later -->
<ContentControl Content="{Binding ViewContent}"/>
这是(简化的)ViewModel:
public class ProductionViewModel : EntityViewModelBase<Production>
{
public T Item { get; set; } // shall be in BaseClass
public ProductionViewModel() {}
public void SetItem(Production model) // shall be in BaseClass
{
Item = model;
}
// a subViewModel
public ArtistgroupListViewModel ArtistgroupListViewModel
{
get
{ // BREAKPOINT 1
ArtistgroupListViewModel vm = new ArtistgroupListViewModel();
//vm.SetArtistgroups(Artistgroups); // that's the goal
vm.SetTestText(Item.Label); // that's for debugging only
return vm;
}
}
//EDIT: added all Properties that live here, but should not be related:
public string LastModified => Item.LastModified.ToShortDateString() + " " + Item.LastModified.ToShortTimeString();
public Workgroup Workgroup => (Workgroup) Task.Run(() => Store.FindItemByIdAsync(typeof(Workgroup), Item.Workgroup.Id)).Result;
public List<BaseModel> Artistgroups => Task.Run(() => Store.QueryAsync(typeof(Artistgroup), new Filter(Item.Artistgroups.Ids))).Result;
}
EntityViewModelBase
的相关部分:
public abstract class EntityViewModelBase<T> : ViewModelBase
where T : BaseModel
{
//public T Item { get; set; }
public EntityViewModelBase()
{
// this gets called
}
//public void SetItem(T currentItem)
//{ // BREAKPOINT 2
// Item = currentItem;
//}
}
然后在SubViewModel ArtistgroupListViewModel
中我只设置了TestText
public string Test { get; set; } = "Test";
public void SetTestText(string txt)
{
Test = txt;
}
并在拟合View.xaml中显示它
在这种配置中一切都很好,并且在View中更新了TestText。
但我其实想要搬家
public T Item { get; set; }
public void SetItem(Production model)
{ // BREAKPOINT 2
Item = model;
}
从ProductionViewModel到EntityViewModelBase(如您所见,已经存在的注释版本)。
但是当我这样做,并在制作之间切换 - 在ProductionViewModel上调用SetItem()
- 文本不再更新。
症状:
Item
或方法SetItem()
移动到EntityViewModelBase,则会出现相同的行为所以问题是: 有没有办法可以移动那两个?如果没有,为什么我必须将它们保留在扩展类中?这与我对扩展课程的理解相矛盾。这是实现INotifyPropertyChanged的问题吗? (虽然我也通过Fody尝试过)
最新版本的所有软件包,.Net 4.6。
EDITS:
ArtistgroupListViewModel的getter是通过xaml中的绑定调用的,如下所示:
<local:ArtistgroupListView DataContext="{Binding Path=ArtistgroupListViewModel, NotifyOnSourceUpdated=True}"/>
我找到了解决方案/我的问题的原因:
它确实是mvvm-light ViewModelLocator或它使用ViewModel的一个实例的事实。
所以我只改变了主要的父ViewModel:
ProductionViewModel pview = new ProductionViewModel(); // no more ServiceLocator...
pview.SetItem((Models.Production) msg.Model);
ViewContent = pview;