Это правильно в вашем конструкторе окон:
DataContext = new ProjectViewModel();
И это должно показать вам некоторые вещи в сетке:
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Id}" Header="ID" />
<DataGridTextColumn Binding="{Binding ProjectTitle}" Header="Project Title" />
<DataGridTextColumn Binding="{Binding ProjectDetails}" Header="Project Details" />
</DataGrid.Columns>
Пользователи WPF обычно не используют материалы панели дизайнера / свойств. Это не здорово и не улучшилось за десять лет. Вам не повезло с автозаполнением и в этом случае.
Предпочитаемый контроль? Зависит от того, что вы хотите: если вам нужно несколько столбцов в строке, используйте DataGrid или ListView. Если вы хотите, чтобы одно значение отображалось в строке, или какой-то симпатичный шаблонный интерфейс в строке, используйте ListBox.
Быстрый список:
<ListBox
ItemsSource=“{Binding Projects}”
DisplayMemberPath=“ProjectTitle”
/>
DisplayMemberPath не привязан. Это строка, которая задает имя свойства того, что вы отображаете в ListBox.
<Ч />
Я бы лично сделал это следующее изменение, хотя оно совершенно необязательно. То, что у вас есть, будет отлично работать: DataGrid.ItemsSource
не возражает против привязки к свойству, объявленному как IEnumerable<T>
. Объявленный тип DataGrid.ItemsSource
не является универсальным System.Collections.IEnumerable
. Но более обычно и часто удобно выставлять наблюдаемую коллекцию, подобную этой.
public ObservableCollection<ProjectModel> Projects
{
get { return _projects; }
}
Когда вы говорите «класс модели», я могу ошибаться, но мне интересно, есть ли здесь терминологическая вещь: ваш ProjectModel
- это класс модели, потому что он в основном POCO («Plan Old CLR Object»), без INotifyPropertyChanged
. Но поскольку он связан в пользовательском интерфейсе, если пользователь может изменить какие-либо свойства, вам понадобится правильная модель представления с INPC. А если нет, установите IsReadOnly="True"
для этой DataGrid. Если проекты просто планируют мертвые данные только для чтения в пользовательском интерфейсе без какого-либо поведения, то POCO, как у вас, - это хорошо. Просто убедитесь, что пользовательский интерфейс действительно только для чтения.
MVVM не означает модель представления, которая владеет моделями. Это означает, что viewmodel владеет viewmodels, которые владеют другими viewmodels, может быть, с дюжиной слоев в глубине, и это «дерево» viewmodel отражает дерево проекта. Затем у вас есть модели, представляющие собой отдельную параллельную иерархию, отражающую необходимую организацию уровня данных. Если вы загружаете проекты из БД через веб-сервис, вы, вероятно, имеете ProjectModel и ProjectViewModel. Но некоторые модели не имеют аналогов модели, а многие модели не имеют аналогов модели.
И небольшому проекту может вообще не понадобиться слой "модель". Когда я учусь, я без колебаний просто пишу модели и виды пока. Овладеть этим и моделями тривиально.
Модель - это просто данные. ProjectViewModel может обернуть ProjectModel, предоставляя идентичные свойства, но с INPC, а также другие свойства, относящиеся к пользовательскому интерфейсу: IsDirty
, например, если он редактируемый, или списки поиска для пользовательского интерфейса для привязки к ComboBox, если он имеет свойства, которые являются тип перечисления или поиска. Он также будет иметь команды и методы. Есть и другие, возможно, более подходящие подходы, чем написание обертки, но уже поздно, и я, к сожалению, в данный момент рисую пробел.