私は非常に奇妙な問題を抱えています。にバインドListBox.ItemSource
していObservableCollection
ます。CollectionChanged
アイテムが追加された場合はコレクションのイベントをサブスクライブし、コレクションListBox
にバインドされているウィンドウを表示します。初めてこれを行うと、本来ListBox
あるべきアイテムが 1 つだけ表示されます。ただし、2 回目はListBox
、新しく作成された にWindow
2 つのアイテムが表示されます。ObservableCollection
に複数のアイテムが含まれていないことを確認しました。一体何が起こっているのですか?
これが私のビューモデルのコードです。
public ObservableCollection<AlarmItemViewModel> RaisedAlarms
{
get { return _raisedAlarms; }
set { _raisedAlarms = value; RaisePropertyChanged("RaisedAlarms"); }
}
protected override void OnAlarmRaised(AlarmItem a_alarmItem)
{
var activeAlarmItems = from alarmItem in RaisedAlarms
select alarmItem.AlarmItem;
if (!activeAlarmItems.Contains(a_alarmItem))
RaisedAlarms.Add(new AlarmItemViewModel(this, a_alarmItem));
}
private void OnActiveAlarmsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
if (_alarmRaiseWindow == null)
{
_alarmRaiseWindow = new SetupWindow();
_alarmRaiseWindow.Title = "Alarm Raised";
_alarmRaiseWindow.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterScreen;
_alarmRaiseWindow.Topmost = true;
_alarmRaiseWindow.Content = new AlarmRaise();
_alarmRaiseWindow.DataContext = this;
_alarmRaiseWindow.Closed += OnAlarmNotifyClosed;
}
}
if (!RaisedAlarms.Any() && _alarmRaiseWindow != null)
{
_alarmRaiseWindow.Close();
}
}
private void OnAlarmNotifyClosed(object sender, EventArgs e)
{
if (_alarmRaiseWindow != null)
{
_alarmRaiseWindow.Closed -= OnAlarmNotifyClosed
_alarmRaiseWindow = null;
}
}
XAML の簡略化されたバージョンを次に示します。
<UserControl x:Class="MyNamespace.AlarmRaise"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300" Width="400" Height="300">
<Border>
<Grid>
<ListBox ItemsSource="{Binding RaisedAlarms, Mode=OneWay}">
</ListBox>
</Grid>
</Border>
</UserControl>
編集:
私のコードの仕組みは基本的にこれです。コレクションの最初のアイテムが追加されると、コレクションの境界Window
を含む が表示されるため、コレクションに他のアイテムが追加されると、それらも表示されます。ListBox
コレクション内の最後のアイテムが削除されると、Window
は閉じられます。
たとえば、「アラーム 1」、「アラーム 2」、「アラーム 3」があり、それらが最初に表示され、5 秒間スリープさせて削除すると、次にウィンドウが表示されたときに表示されます。最初の項目を 2 回: 「アラーム 1」、「アラーム 1」、「アラーム 2」、「アラーム 3」。必ずしもその順序ではありません。
これは、後続の反復にも当てはまります (つまり、2 倍以上に表示されることはありません)。
さらに編集:
問題はビューまたはバインディングのいずれかにあるようです。ビューモデルは常に正しいデータを正しいタイミングで表示しています。何らかの方法でバインディングを更新する必要があるか、コードでバインドする必要があるかどうか疑問に思っています。どちらも避けたい。