I have a very weird problem. I am binding ListBox.ItemSource
to an ObservableCollection
. I subscribe to the CollectionChanged
event of the collection if any items are added, I show the window with the ListBox
that is bound to the collection. The first time I do this, the ListBox
shows only one item as it should. The second time however, the ListBox
which is in a newly created Window
shows two items. I have verified that the ObservableCollection
never has more than one item in it. What the heck is going on?
Here is the code in my view model.
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;
}
}
Here is a simplified version of the 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>
Edits:
The way my code works is basically this. When the first item in the collection is added it shows a Window
containing a ListBox
bound the collection, so if any others are added in the collection they will show as well. Once the last item in the collection is removed, the Window
is closed.
So say I have an "Alarm 1", "Alarm 2" and "Alarm 3", and they show the first time, and I remove them by sleeping them for five seconds, then the next time the window comes up, it will show the first item twice: "Alarm 1", "Alarm 1", "Alarm 2", "Alarm 3". Not always in that order.
This is true for subsequent iterations as well (i.e. it never shows up more than doubled).
Further Edits:
It seems that the issue is either with the view or the binding. The view model is always showing the correct data at the correct times. I am wondering if maybe I need to refresh the binding in some way, or bind in code. I am wanting to avoid both.