ListBox绑定导致加倍项

时间:2012-07-16 17:39:00

标签: wpf data-binding listbox

我有一个非常奇怪的问题。我将ListBox.ItemSource绑定到ObservableCollection。如果添加了任何项目,我订阅集合的CollectionChanged事件,我会显示绑定到集合的ListBox窗口。我第一次这样做时,ListBox只显示一个项目。但是,第二次,新创建的ListBox中的Window显示了两个项目。我已经确认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”,他们第一次显示,我将它们睡了五秒钟,然后下一次窗口出现时删除它们,它将显示第一个项目两次:“报警1”,“报警1”,“报警2”,“报警3”。并不总是按照这个顺序。

对于后续迭代也是如此(即它从未显示超过两倍)。

进一步修改

似乎问题出在视图或绑定上。视图模型始终在正确的时间显示正确的数据。我想知道是否需要以某种方式刷新绑定,或者在代码中绑定。我想避免两者。

1 个答案:

答案 0 :(得分:0)

哇哇,我已经解决了这个问题!这与设置DataContext和调用Show()的顺序有关。如果我在之后设置DataContext ,我可以正常工作Window.Show()。糟糕,我在示例代码中省略了对Show()的调用。我不得不更改代码以删除与此问题无关的外部依赖,并且会提出更多问题。我现在要编辑它。