[英]C# wpf listview binding problem with observable collection
我按照这个教程创建了一个日历/计划: https ://www.codeproject.com/Articles/35490/Creating-the-Microsoft-Outlook-Appointment-View-in Listview包含5个项目,源
<!--<ListView.Items>
<local:Termin Start="10/28/2021 6:00 AM" Finish="10/28/2021 4:00 PM" Subject="Meet with John" Location="Southwest Meeting Room" Organizer="Jim Smith" />
<local:Termin Start="10/29/2021 6:00 AM" Finish="10/29/2021 4:00 PM" Subject="Meet with Rick" Location="Southwest Meeting Room" Organizer="Jim Smith" />
<local:Termin Start="10/30/2021 6:00 AM" Finish="10/30/2021 6:00 PM" Subject="Meet with Dave" Location="Southwest Meeting Room" Organizer="Jim Smith" />
<local:Termin Start="10/31/2021 6:00 AM" Finish="10/31/2021 6:00 PM" Subject="Meet with Larry" Location="Southwest Meeting Room" Organizer="Jim Smith" />
<local:Termin Start="10/31/2021 6:00 AM" Finish="10/31/2021 6:00 PM" Subject="Meet with Jim" Location="Southwest Meeting Room" Organizer="Jim Smith" />
</ListView.Items>-->
现在,当我尝试用可观察的集合替换硬编码的项目时
<ListView ItemsSource="{Binding Termine}">
<ListView.View>
<controls:CalendarView ItemBeginBinding="{Binding Start}" ItemEndBinding="{Binding Finish}">
`
public class KalenderVM : BewohnerVM
{
public KalenderVM()
{
DateTime dateValue1;
DateTime dateValue2;
DateTime.TryParse("25.10.2021 6:00", out dateValue1);
DateTime.TryParse("25.10.2021 16:00", out dateValue2);
Termine.Add(new Termin(dateValue1, dateValue2, "Jan", "Anker"));
DateTime.TryParse("26.10.2021 6:00", out dateValue1);
DateTime.TryParse("26.10.2021 16:00", out dateValue2);
Termine.Add(new Termin(dateValue1, dateValue2, "Jan", "Anker"));
DateTime.TryParse("27.10.2021 6:00", out dateValue1);
DateTime.TryParse("27.10.2021 18:00", out dateValue2);
Termine.Add(new Termin(dateValue1, dateValue2, "Jan", "Frei"));
}
private ObservableCollection<Termin> _termine = new ObservableCollection<Termin>();
public ObservableCollection<Termin> Termine
{
get { return _termine; }
set { _termine = value; }
}
public partial class Kalender : UserControl
{
public Kalender()
{
InitializeComponent();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IWHRManagment.Models
{
public class Termin
{
public Termin(DateTime start, DateTime finish, string orga, string sub)
{
Start = start;
Finish = finish;
Organizer = orga;
Subject = sub;
Location = "Home";
}
public Termin() { }
public DateTime Start { get; set; }
public DateTime Finish { get; set; }
public bool Recurring { get; set; }
public object Interval { get; set; }
public string Organizer { get; set; }
public string Subject { get; set; }
public string Location { get; set; }
}
}
ListView 包含 2 个项目(我为测试目的创建了 2 个)但没有显示项目,因为“开始”和“完成”“在 ViewModel 中找不到”......我尝试了一个静态资源,几个相对来源,但我仍然有困难以正确的方式去做。
有人可以帮助我并告诉我正确的方法吗?
这是 MVVM 中的一个简单 LV。 你在命名方面有点混乱:只要保持xxxViewModel
等; 不要走捷径。
我正在粘贴简单 ListView 的简单 MVVM 示例,该示例由 ItemViewModel 类包装并由 XAML 绑定。
如果您没有意识到危险,请不要从用户控制开始您的工作。 他们需要不同的处理和绑定。
我特意用 ViewModel 包装了一个基本模型(databaseentry)对象。 将来,更新属性会更容易,而且您不会为“如何将 inotifychanged 添加到实体框架”而烦恼。 更多样板,但我希望它会起作用。
如果你不明白一些事情,然后尝试。 有黑客。 如果你从 'xaml' 初始化视图模型,就像我在这里所做的那样,那么不要声明datacontext = new AnyViewModel()
因为你会失败。
总的来说,我认为 MVVM 是一个糟糕的选择。 绑定是 WinForms/QT 中一直缺乏的东西,现在它们来了。 但是既然你有了绑定,你就开始在通信上挣扎和挣扎,然后你添加和添加类、数据类、服务和 bla bla。 越多的人使用模板和泛型,越多的代码变得一团糟。
VIEWMODEL(为简单起见集成):
using Pjoter2000.View;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pjoter2000.ViewModel
{
public class DatabaseEntry // EntityFramework as an example
{
public int ID { get; set; }
public string DataName { get; set; }
}
// MVVM wrapper for single item, Inotifypropertychanged should be a class that simplifiesr wrapping
public class SomeItemViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
private DatabaseEntry _item;
public string Name
{
get => _item.DataName;
set
{
_item.DataName = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Name)));
}
}
SomeItemViewModel() { } //wtf? :)
public SomeItemViewModel(DatabaseEntry entry)
{
_item = entry;
}
}
public class PoligonViewModel
{
ObservableCollection<SomeItemViewModel> _records;
public ObservableCollection<SomeItemViewModel> Records
{
get => _records;
set
{
_records = value;
}
}
public PoligonViewModel()
{
// INIT Records
Records = new ObservableCollection<SomeItemViewModel>();
// Fetching data from model (DB), abstract
for (int i = 0; i < 10; i++)
{
var item = new DatabaseEntry()
{
DataName = "Name " + i.ToString()
};
// Wrapping database model data into itemviewmodel (some say it's more flexible and might be ok in future)
Records.Add(new SomeItemViewModel(item));
}
}
}
}
看法:
using System.Windows;
namespace Pjoter2000.View
{
public partial class Poligon : Window
{
public Poligon()
{
InitializeComponent(); // Current data context is poligonviewmodel, because it's set from xaml already
}
}
}
XAML
<Window x:Class="Pjoter2000.View.Poligon"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewmodel="clr-namespace:Pjoter2000.ViewModel"
mc:Ignorable="d"
Title="Poligon" Height="400" Width="514">
<Window.DataContext>
<!-- THIS PART CREATES VIEW MODEL CLASS, DON'T CREATE IT IN CONSTRUCTOR -->
<viewmodel:PoligonViewModel/>
</Window.DataContext>
<Grid>
<ListView ItemsSource="{Binding Records}">
<!-- This is the main view of the list, so I declare the view here -->
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</Window>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.