ViewModel - не обновляется на унаследованных свойствах - PullRequest
0 голосов
/ 29 марта 2019

У меня есть модель представления ProductionViewModel, которая расширяет более общий EntityViewModelBase<T>, который снова расширяет ViewModelBase mmvm-источника света (который происходит от ObservableObject).

При вызове этой модели представления я устанавливаю базовые данныечерез его метод 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

В этой конфигурации все хорошо , и TestText get обновляется в представлении.

Но Я действительно хотел переместить

public T Item { get; set; }

public void SetItem(Production model)
{                                     // BREAKPOINT 2
    Item = model;
}

из ProductionViewModel в EntityViewModelBase (как вы можете видеть, комментированные версии уже живут там).
Но когда я делаю это, и переключаюсь между продукцией - что вызывает SetItem() в ProductionViewModel - текст больше не обновляется.

Симптомы:

  • Получается точка останова 2, обновляется сама добыча в ProductionView.xaml
  • Точка останова 1 (SetTestText) не получить изменение при изменении, поэтому TestText не обновляется.
  • То же поведение, если я перемещаю только свойство Item или метод SetItem() в EntityViewModelBase

Итак, вопросы:
Есть ли способ, которым я могу переместить эти два?И если нет, то почему я должен держать их в расширенном классе?Это противоречило бы моему пониманию расширения классов.Это вопрос реализации INotifyPropertyChanged?(Хотя я тоже пробовал через Fody)

Все пакеты последней версии .Net 4.6.

РЕДАКТИРОВАТЬ:

Получатель ArtistgroupListViewModel вызывается через привязку в xaml следующим образом:

<local:ArtistgroupListView DataContext="{Binding Path=ArtistgroupListViewModel, NotifyOnSourceUpdated=True}"/>

1 Ответ

0 голосов
/ 29 марта 2019

Я нашел решение / причину моей проблемы:

Это действительно был ViewModelLocator mvvm-light или тот факт, что он использует один экземпляр ViewModel.

Так что я изменил только в главном родительском VieModel:

ProductionViewModel pview = new ProductionViewModel(); // no more ServiceLocator...
pview.SetItem((Models.Production) msg.Model);
ViewContent = pview;
...