Я очень новичок в MVVM, и я просто пытаюсь намочить ноги небольшим приложением тестирования wpf. У меня есть модельный вызов ToDoItemModel, определенный ниже: (в основном у меня есть класс под названием ToDoItemModel и ToDoItemListModel, который реализует IList
public class ToDoItemModel
{
private DateTime _TodoDate;
private string _TodoDescription;
private TimeSpan _TodoTimeSpan;
private string _StartTime;
public ToDoItemModel(DateTime d, string s)
{
_TodoDate=d;
_TodoDescription=s;
}
public string StartTime
{
get { return _StartTime; }
set { _StartTime = value; }
}
public TimeSpan ToDoTimeSpan
{
get { return _TodoTimeSpan; }
set { _TodoTimeSpan = value; }
}
public string ToDoDescription
{
get { return _TodoDescription; }
set { _TodoDescription = value; }
}
public DateTime ToDoDate
{
get { return _TodoDate; }
set { _TodoDate = value; }
}
public override string ToString()
{
return string.Format("Date: {0}- Time: {1}- Duration: {2}- Description: {3}",_TodoDate.ToString("d"),_StartTime,_TodoTimeSpan,_TodoDescription);
}
}
public class ToDoListModel: IList<ToDoItemModel>
{
private readonly IList<ToDoItemModel> _todoList = new List<ToDoItemModel>();
public ToDoListModel()
{
//Hard code this one for testing purpose
_todoList.Add(new ToDoItemModel(DateTime.Now,"Testing"));
}
public int IndexOf(ToDoItemModel item)
{
return _todoList.IndexOf(item);
}
public void Insert(int index, ToDoItemModel item)
{
_todoList.Insert(index,item);
}
public void RemoveAt(int index)
{
_todoList.RemoveAt(index);
}
public ToDoItemModel this[int index]
{
get
{
return _todoList[index];
}
set
{
_todoList[index]=value;
}
}
public void Add(ToDoItemModel item)
{
_todoList.Add(item);
}
public void Clear()
{
_todoList.Clear();
}
public bool Contains(ToDoItemModel item)
{
return _todoList.Contains(item);
}
public void CopyTo(ToDoItemModel[] array, int arrayIndex)
{
_todoList.CopyTo(array,arrayIndex);
}
public int Count
{
get { return _todoList.Count; }
}
public bool IsReadOnly
{
get { return _todoList.IsReadOnly; }
}
public bool Remove(ToDoItemModel item)
{
return _todoList.Remove(item);
}
public IEnumerator<ToDoItemModel> GetEnumerator()
{
return _todoList.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
Я хотел бы отобразить на моем представлении datagrid, который будет привязан к ToDoListModel через ToDoListModelView, который наследуется от ObservableObject. ObservableObject реализует INotifyPropertyChanged
public class ToDoListModelView:ObservableObject
{
ToDoListModel _myModel = new ToDoListModel();
...
}
Мое мнение определяется кодом xaml ниже: В принципе, я хотел бы привязать этот datagrid к моей ToDoListModel.
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TestWPF" x:Class="TestWPF.MainWindow"
Title="MainWindow" Height="350" Width="525">
<Grid Margin="1,0,-1,0">
<DataGrid x:Name="ExistingToDoList"
HorizontalAlignment="Left"
Margin="33,201,0,0"
VerticalAlignment="Top"
Height="94" Width="464"
Background="#FFF1E6E6"
GridLinesVisibility="Horizontal"
ItemsSource="{Binding ToDoListModelView}"
Style="{DynamicResource ToDoEntry}">
<DataGrid.DataContext>
<local:ToDoListModel/>
</DataGrid.DataContext>
</DataGrid>
</Grid>
</Window>
Однако после нажатия F5 программа запустилась, но я не вижу содержимого, связанного с данными, хотя у меня есть как минимум 1 элемент в списке. Что я сделал неправильно? Я знаю, что это далеко не полный, но, по крайней мере, я должен увидеть ToDoItem в списке из datagrid? Что я пропустил? Пожалуйста помоги. Благодарю!
---- Мое обновление -------------------------------------------- -
ToDoListModel наследует от List с свойством ToDoList, который возвращает базовые данные
public class ToDoListModel: List<ToDoItemModel>
{
private List<ToDoItemModel> _todoList = new List<ToDoItemModel>();
public List<ToDoItemModel> TodoList
{
get { return _todoList; }
}
public ToDoListModel()
{
_todoList.Add(new ToDoItemModel(DateTime.Now,"Testing"));
}
Я также исправил datagrid для привязки к ToDoList и установил autoGeneratecolumn в true для простоты и иллюстрации.
<Grid Margin="1,0,-1,0" d:DataContext="{d:DesignData /SampleData/ToDoListModelSampleData.xaml}">
<DataGrid x:Name="ExistingToDoList"
HorizontalAlignment="Left"
Margin="33,201,0,0"
VerticalAlignment="Top"
Height="94" Width="464"
Background="#FFF1E6E6"
GridLinesVisibility="Horizontal"
ItemsSource="{Binding TodoList}"
Style="{DynamicResource ToDoEntry}"
AutoGenerateColumns="True"
DataContext="{Binding Mode=OneWay}">
<DataGrid.ItemBindingGroup>
<BindingGroup/>
</DataGrid.ItemBindingGroup>
</DataGrid>
Вы устанавливаете свойство DataContext
классу "Model" (что-то, чего вы никогда не должны делать, всегда устанавливаете в класс ViewModel), который не имеет свойства "ToDoListModelView", поэтому привязка не работает (вы должны увидеть это как Систему. Исключение данных в окне вывода).
Writing ItemsSource="{Binding ToDoListModelView}"
говорит: "Ищите свойство, называемое" ToDoListModelView "в моем DataContext, и используйте его как мой ItemSource". Вероятно, вы планировали:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TestWPF" x:Class="TestWPF.MainWindow"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:ToDoListModelView/>
</Window.DataContext>
<Grid Margin="1,0,-1,0">
<DataGrid x:Name="ExistingToDoList"
ItemsSource="{Binding MyModelProperty}"
</DataGrid>
</Grid>
</Window>
Обратите внимание, что я установил DataContext
в объект ViewModel (а не в модель), и я установил его для окна. Это чисто стилистика, но вы обычно не устанавливаете специфическое свойство DataContext управления (хотя бывают случаи, когда это необходимо). Затем я связываюсь с (воображаемым) свойством, которое, вероятно, будет экземпляром ToDoListModel
.
Несколько других сторон:
IList
вы, вероятно, ошибаетесь! Что случилось с ObservableCollection
или одной из других существующих реализаций?Аналогичный, но не дубликат (ответ может помочь вам: установка DataContext в XAML в WPF)