#wpf #mvvm #entity-framework-4 #inotifypropertychanged
#wpf #mvvm #entity-framework-4 #inotifypropertychanged
Вопрос:
Я уже успешно использовал принципы MVVM в предыдущих проектах, но я кое с чем застрял… очень простой!
Использование EF4.1 (подход с первым кодом) в качестве моего доступа к хранилищу данных, который работает нормально. Создан следующий класс:
public class Photo
{
[Key]
public int PhotoId { get; set; }
public string Year { get; set; }
public byte[] Thumbnail { get; set; }
public DateTime InsertTime { get; set; } //insertion time
public DateTime UpdateTime { get; set; } //last modification time
//navigational properties
public virtual Image Image { get; set; }
public virtual Monument Monument { get; set; }//a Photo belongs to a specific Monument
public virtual MDPremisesSpace MDPremisesSpace { get; set; } //a Photo was shot at specific premises space
public virtual MDRestauration MDRestauration { get; set; }//a Photo has a restauration
public virtual MDMaintenance MDMaintenance { get; set; }//a Photo has a maintenance
public virtual MDType MDType{ get; set; }//a Photo has a type
public virtual User InsertUser { get; set; } //the user who inserted this reocord
public virtual User UpdateUser { get; set; } //the user who lastly modified this reocord
//constructor
public Photo()
{
}
}
Создал Viemodel на основе этого класса (я использую Viewmodel на основе generics, чтобы повторно использовать его везде, где я могу — с успехом), который реализует INotifyPropertyChanged.В этой viewmodel также есть свойство Monuments, которое определено таким образом (работает нормально):
private ObservableCollection<Model.Monument> monuments = new ObservableCollection<Model.Monument>();
public ObservableCollection<Model.Monument> Monuments
{
get { return monuments; }
private set { monuments = value; }
}
Создал представление, в котором я использовал выпадающий список, подобный этому:
<ComboBox Name="cmbMonument" Grid.Row="1" Grid.Column="1" Width="200" HorizontalAlignment="Left"
ItemsSource="{Binding Path=Monuments }"
SelectedItem="{Binding Path=SelectedRecord.Monument,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
DisplayMemberPath="Name"
/>
Значения отображаются корректно (и их также можно правильно сохранить).
НО:
Есть ли кто-нибудь, кто может объяснить, почему изменение выбранного элемента в выпадающем списке НЕ вызывает уведомления об изменении свойства??
Если бы я изменил свойство Year, уведомление было бы поднято!!
(я подозреваю тот факт, что свойство Monument в классе Photo выше является навигационным свойством … но даже если это так, разве оно не должно вызывать уведомление?)
Любые подсказки в основном приветствуются!!
Ответ №1:
Согласно этому сайту, это может быть ошибкой.
Какого уведомления вы ожидаете? Все, что делает привязка, это то, что она изменяет свойство Monument, если установщик этого свойства не вызывает никаких уведомлений, вы не получите никаких уведомлений.
Комментарии:
1. Итак, почему это работает для свойства Year (я нигде не определил явное повышение уведомления для любого свойства)?
2. Аааа!! я вижу .. теперь это имеет больше смысла (после прочтения жалобы на ошибку). Но я уверен, что я делаю что-то не так… может быть, так я определил класс Photo … мне нужно покопаться!!
Ответ №2:
Что ж, оказывается, что мои подозрения верны!
Правильный способ объявить этот тип кода первым классом в EF4.1 заключается в следующем:
public class Photo
{
[Key]
public int PhotoId { get; set; }
public int? MonumentId { get; set; }
public int? MDPremisesSpaceId { get; set; }
public int? MDRestaurationId { get; set; }
public int? MDMaintenanceId { get; set; }
public int? MDTypeId { get; set; }
public string Year { get; set; }
public byte[] Thumbnail { get; set; }
public int? InsertUserId { get; set; } //the Id of user who inserted this record
public DateTime InsertTime { get; set; } //insertion time
public int? UpdateUserId { get; set; } //the Id of last user who modified this record
public DateTime UpdateTime { get; set; } //last modification time
//navigational properties
public virtual Image Image { get; set; }
[ForeignKey("MonumentId")]
public virtual Monument Monument { get; set; }//a Photo belongs to a specific Monument
[ForeignKey("MDPremisesSpaceId")]
public virtual MDPremisesSpace MDPremisesSpace { get; set; } //a Photo was shot at specific premises space
[ForeignKey("MDRestaurationId")]
public virtual MDRestauration MDRestauration { get; set; }//a Photo has a restauration
[ForeignKey("MDMaintenanceId")]
public virtual MDMaintenance MDMaintenance { get; set; }//a Photo has a maintenance
[ForeignKey("MDTypeId")]
public virtual MDType MDType { get; set; }//a Photo has a type
[ForeignKey("InsertUserId")]
public virtual User InsertUser { get; set; } //the user who inserted this reocord
[ForeignKey("UpdateUserId")]
public virtual User UpdateUser { get; set; } //the user who lastly modified this reocord
//constructor
public Photo()
{
}
}
Обратите внимание, что каждая ассоциация внешнего ключа также имеет свое свойство в классе. Теперь происходит уведомление об изменении свойства!