Entity Framework CTP5 Code First, WPF - моделирование MVVM

У меня есть моя модель, полностью настроенная для моего приложения WPF, и сначала я работаю с кодом ctp5 entity framework, вот образец класса модели:

public class Task
{
    public int ID { get; set; }
    public int Index { get; set; }
    public string Content { get; set; }
    public int Indentation { get; set; }
    public DateTime Start { get; set; }
    public decimal Effort { get; set; }
    public decimal CompletedEffort { get; set; }
    public decimal Cost { get; set; }
}

Каким будет рекомендуемый способ построения моей модели представления? Мои модели представления будут реализовывать INotifyPropertyChanged, я не хочу, чтобы классы моделей имели какой-либо конкретный код пользовательского интерфейса, чтобы их можно было легко повторно использовать в других приложениях. Должен ли я сделать все свойства модели виртуальными, а затем переопределить их в модели представления? (кажется, много ненужного кодирования ...) Будет ли код EF хорошо работать с этим типом формата?

Изменить. Это несколько похожий вопрос В MVVM должна ли ViewModel или Model реализовывать INotifyPropertyChanged?, однако единственные решения, похоже, добавляют в модель то, что я считаю логикой пользовательского интерфейса. Возможно, я могу добавить в модель какой-то делегат и подключиться к нему из модели просмотра, которая, в свою очередь, будет использовать INotifyPropertyChanged ... что-то вроде этого?

    public class Task
    {
        public delegate void HandleChange(string propertyName);
        public HandleChange ChangeHandler;

        public int ID 
        { 
            get
            {
                return ID;
            } 
            set
            {
                if(ID != value)
                {
                    ID = value;
                    ChangeHandler("ID");
                }
            }
        }
...

person Chris Klepeis    schedule 21.02.2011    source источник
comment
Крис, ваш Edit: это в основном реализация INotifyPropertyChanged! Ваш делегат HandleChange имеет то же назначение, что и делегат PropertyChangedEventHandler, а переменная ChangeHandler имеет то же назначение, что и PropertyChanged. Единственное отличие состоит в том, что вы не помечаете ChangeHandler как event (это всего лишь механизм защиты, позволяющий только подписку и отказ от подписки, но запрещающий, например, устанавливать для обработчика значение null). Кстати: INotifyPropertyChanged находится в сборке System.dll, пространство имен System.ComponentModel; это вообще не имеет ничего общего с WPF или UI.   -  person Slauma    schedule 21.02.2011


Ответы (2)


Что я делаю, так это создать экземпляр моего класса модели для свойства в ViewModel, а затем реализовать INotifyPropertyChanged непосредственно в Model для свойств Model и в ViewModel только для экземпляра Model, например:

public class Task : INotifyPropertyChanged
{
    // Implementation of INotifyPropertyChanged
    // Raising the PropertyChanged event in the Setters of all properties
}

public class TaskViewModel : INotifyPropertyChanged
{
    private Task _task;
    public Task Task
    {
        get
        {
            return _task;
        }
        set
        {
            if (_task != value)
            {
                _task = value;
                RaisePropertyChanged("Task");
            }
        }
    }

    // INotifyPropertyChanged implementation
}

Затем в XAML я привязываюсь непосредственно к свойствам модели, например:

<TextBox Text="{Binding Task.Content}" />

(TaskViewModel будет здесь DataContext для представления.)

Я делаю это в основном для того, чтобы избежать упомянутого вами «большого количества ненужного кодирования», и я не смог найти недостатка. (Я также делаю свою модель постоянной с помощью EF Code-First.)

person Slauma    schedule 21.02.2011
comment
@Slauna - Если классы вашей модели реализуют INotifyPropertyChanged, тогда зачем вообще беспокоиться о MVVM? Основным преимуществом MVVM IMO является разделение проблем, так что объекты базовой модели могут быть более легко использованы в других проектах. Мой проект довольно большой, поэтому я легко могу представить, что хочу использовать базовые модели в службах WCF, приложениях ASP.Net и т.д. - person Chris Klepeis; 21.02.2011
comment
В данном конкретном случае это может быть допустимое решение, но часто у вас нет кода для модели, поэтому вы не можете заставить его реализовать INotifyPropertyChanged ... - person Thomas Levesque; 21.02.2011
comment
@Chris: 1) INotifyPropertyChanged содержит только общее событие .NET, которое делает изменения объекта наблюдаемыми извне. Я могу подписаться на него в любом контексте, а не только в WPF / MVVM. Это событие может найти применение и в других проектах. Если мне это не нужно, я не подписываюсь. Изменение свойства модели - это проблема модели, поэтому я не считаю, что нарушаю разделение ответственности. 2) Конечно, ViewModels имеет больше, чем только экземпляр модели, например, команды, которые привязаны к действиям пользовательского интерфейса и действительно не принадлежат модели, ... (продолжение) - person Slauma; 21.02.2011
comment
(продолжить) ... или другие свойства, специфичные для пользовательского интерфейса, которые не могут быть напрямую сопоставлены со свойствами модели. Итак, для всего этого мне еще нужна ViewModel. Тем не менее, я могу понять, что вам не нравится это решение, мне оно тоже не понравилось, прежде чем я решил это сделать. Но я не видел альтернативы ни этому способу, ни копированию всех свойств модели в ViewModel и сопоставлению между свойством Model и ViewModel по свойству. Мои классы Model стали толще (они также реализуют IDataErrorInfo), но все еще не связаны с WPF. - person Slauma; 21.02.2011
comment
@Slauma - Спасибо за разъяснения! Я тоже могу пойти по этому пути. - person Chris Klepeis; 21.02.2011
comment
@Chris: Если вы должны найти другой способ, помимо этого решения и копирования всех свойств в ViewModel, можете ли вы добавить здесь короткий комментарий? Мне тоже было бы очень интересно;) - person Slauma; 21.02.2011
comment
@Slauma - похоже, это хорошее начало stackoverflow.com/questions/772214/ - person Chris Klepeis; 21.02.2011
comment
@Chris: Это интересное обсуждение. Здесь я в основном согласен с ответом Пауло Соуза, особенно: «Тем не менее, существуют разные способы достижения целей, но я всегда буду спорить в пользу простоты и избегать дублирования». Пока я могу сделать это просто, не разрушая преимуществ MVVM, связанных с разделением ответственности, тестируемостью ViewModel и т. Д., Я бы так и поступил. Но не всегда получается. Томас Левеск в своем комментарии выше назвал причину, по которой вы не можете получить уведомление об изменении в модели. И могут быть другие причины, это всегда зависит от ... - person Slauma; 21.02.2011

Я знаю, что это старая ветка, но я искал в Google эту самую тему и наткнулся на эту статью blogs.msdn.com: http://bit.ly/iE3KHI

Короче говоря, начиная с CTP 4 EF CodeFirst появляется новое свойство объекта CodeFirst dbSet .Local. .Local - это коллекция ObservableCollection, которая реализует INotifyPropertyChanged. Итак, если у вас есть код сначала dbcontext, который предоставляет DbSet (Of Task) под названием Tasks, вы можете установить контекст данных вашей формы на Tasks.Local.

person K4GDW    schedule 24.05.2011