【发布时间】:2012-05-02 23:54:42
【问题描述】:
我正在尝试在 WPF ListView 中显示警报列表。为此,我将列表框数据绑定到包含警报列表的属性。由于我使用 MVC 编程范例,因此该属性位于控制器中,并且视图的数据上下文设置为该控制器。
我注意到,当我向列表中添加警报时,视图没有显示新警报。经过一番研究,我发现我需要使用 ObservableCollection 类来正确执行此操作。
但是,显示警报列表并不是唯一需要做的事情,所以我不能/不想将列表的变量类型更改为 ObservableCollection。
我现在尝试创建 ObservableCollection 类型的属性,但这也不起作用。这很正常,因为我没有将警报添加到属性中,而是将其添加到变量中,该变量仍然是 List 类型。
有没有办法在更新列表时告诉属性,或者有其他/更好的方式来显示我的警报并让它们易于用于程序的其他部分?
编辑:
我的解决方法:我通过从我的警报变量中清除 PropertyChanged 事件的事件处理程序中的属性 FutureEvents 来触发 PropertyChanged 事件。
我的代码: cMain 类 { 私有静态易失 cMain 实例; 私有静态对象 syncRoot = new Object();
ObservableCollection<Alarm> alarms;
#region properties
/// <summary>
/// Returns the list of alarms in the model. Can't be used to add alarms, use the AddAlarm method
/// </summary>
public ObservableCollection<Alarm> Alarms
{
get
{
return alarms;
}
}
/// <summary>
/// Returns the ObservableCollection of future alarms in the model to be displayed by the vieuw.
/// </summary>
public ObservableCollection<Alarm> FutureAlarms
{
get
{
//Only show alarms in the future and alarm that recure in the future
var fAlarms = new ObservableCollection<Alarm>(alarms.Where(a => a.DateTime > DateTime.Now || (a.EndRecurrency != null && a.EndRecurrency > DateTime.Now)));
return fAlarms;
}
}
/// <summary>
/// Returns a desctription of the date and time of the next alarm
/// </summary>
public String NextAlarmDescription
{
get
{
if (alarms != null)
{
return alarms.Last().DateTimeDescription;
}
else
{
return null;
}
}
}
#endregion //properties
#region public
/// <summary>
/// Returns the instance of the singleton
/// </summary>
public static cMain Instance
{
get
{
if (instance == null) //Check if an instance has been made before
{
lock (syncRoot) //Lock the ability to create instances, so this thread is the only thread that can excecute a constructor
{
if (instance == null) //Check if another thread initialized while we locked the object class
instance = new cMain();
}
}
return instance;
}
}
/// <summary>
/// Shows a new intance of the new alarm window
/// </summary>
public void NewAlarmWindow()
{
vNewAlarm newAlarm = new vNewAlarm();
newAlarm.Show();
}
public void AddAlarm(Alarm alarm)
{
alarms.Add(alarm);
}
public void RemoveAlarm(Alarm alarm)
{
alarms.Remove(alarm);
}
public void StoreAlarms()
{
mXML.StoreAlarms(new List<Alarm>(alarms));
}
#endregion //public
#region private
//Constructor is private because cMain is a singleton
private cMain()
{
alarms = new ObservableCollection<Alarm>(mXML.GetAlarms());
alarms.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(alarms_CollectionChanged);
}
private void alarms_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
FutureAlarms.Clear(); //Needed to trigger the CollectionChanged event of FutureAlarms
StoreAlarms();
}
#endregion //private
}
【问题讨论】:
标签: c# .net wpf data-binding observablecollection