可观察集合的 C# wpf listview 绑定问题
Posted
技术标签:
【中文标题】可观察集合的 C# wpf listview 绑定问题【英文标题】:C# wpf listview binding problem with observable collection 【发布时间】:2021-12-15 01:55:15 【问题描述】:我按照本教程创建日历/时间表: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 中找不到”“开始”和“完成”......我尝试了一个静态资源,几个相对源但我仍然很难以正确的方式做到这一点。
有人可以帮助我并告诉我正确的方法吗?
【问题讨论】:
请发布您的代码隐藏(ViewModel、C# 代码),而不仅仅是标记。如果我们看不到 ViewModel,我们无法告诉您为什么 ViewModel 中缺少属性 添加了模型、代码隐藏和虚拟机。controls:CalendarView
来自哪里,在您的<ListView.View>
中?您永远不会定义 CalendarView,但据说其中定义了名为 ItemBeginBinding
和 ItemEndBinding
的属性。另外,你的 DataContext 设置了吗?在这种情况下,您的构造函数中必须有类似 DataContext = this
的内容或类似的 KalenderVM
【参考方案1】:
这是 MVVM 中的一个简单 LV。您的命名有点混乱:请保留xxxViewModel
等;不要走捷径。
我正在粘贴简单 ListView 的简单 MVVM 示例,它由 ItemViewModel 类包装并由 XAML 绑定。
如果您没有意识到危险,请不要从用户控件开始您的工作。它们需要不同的处理和绑定。
我有意用 ViewModel 包装了一个基本模型(数据库条目)对象。将来,更新属性会更容易,您不会为“如何将 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>
【讨论】:
以上是关于可观察集合的 C# wpf listview 绑定问题的主要内容,如果未能解决你的问题,请参考以下文章
为啥我的 ListView 数据绑定到可观察集合不能正确显示
WPF ListView 忽略 SelectedItem-change