1

私は非常に奇妙な問題を抱えています。にバインドListBox.ItemSourceしていObservableCollectionます。CollectionChangedアイテムが追加された場合はコレクションのイベントをサブスクライブし、コレクションListBoxにバインドされているウィンドウを表示します。初めてこれを行うと、本来ListBoxあるべきアイテムが 1 つだけ表示されます。ただし、2 回目はListBox、新しく作成された にWindow2 つのアイテムが表示されます。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 倍以上に表示されることはありません)。

さらに編集:

問題はビューまたはバインディングのいずれかにあるようです。ビューモデルは常に正しいデータを正しいタイミングで表示しています。何らかの方法でバインディングを更新する必要があるか、コードでバインドする必要があるかどうか疑問に思っています。どちらも避けたい。

4

1 に答える 1

0

うわー、私は問題を解決しました!DataContext設定と呼び出しの順序に関係していましたShow()。を呼び出したDataContext にを設定すると、正常に動作しますWindow.Show()。おっと、Show()サンプル コードで への呼び出しを省略しました。この問題とは関係のない外部依存関係を削除するために、コードを変更する必要があり、さらに質問をする必要がありました。私は現在それを編集します。

于 2012-07-17T16:35:50.900 に答える