WPF ListViewでアラームのリストを表示しようとしています。これを実現するために、Listbox をアラームのリストを含むプロパティにデータバインドしました。私は MVC プログラミング パラダイムを使用しているため、プロパティはコントローラーに配置され、ビューのデータ コンテキストはそのコントローラーに設定されます。
リストにアラームを追加したときに、ビューに新しいアラームが表示されないことに気付きました。いくつかの調査の結果、これを正しく行うには ObservableCollection クラスを使用する必要があることがわかりました。
ただし、アラームのリストを表示することだけが必要なわけではないため、リストの変数タイプを ObservableCollection に変更することはできません/したくありません。
ObservableCollection 型のプロパティを作成しようとしましたが、これも機能しません。プロパティにアラームを追加せず、List 型のままである変数に追加するので、これはごく普通のことです。
リストが更新されたときにプロパティに通知する方法、またはアラームを表示してプログラムの他の部分で使いやすくする他の/より良い方法はありますか?
編集:
私の回避策:PropertyChanged
イベントの eventhandler にあるプロパティ FutureEvents をPropertyChanged
アラーム変数からクリアすることで、イベントをトリガーします。
私のコード: class cMain { private static volatile cMain instance; プライベート静的オブジェクト 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
}