Popup 中的 ItemsControl 复制添加的第一个项目

ItemsControl inside Popup duplicates the first item added

我在 Popup 中有一个 ItemsControl 和一个 ObservableCollection,我简称为 'Collection',绑定到 ItemsControl.ItemsSource 属性.

ItemsControl 将始终复制第一个添加到 Collection 的项目。 ItemsControl 之后添加的每个项目都会正确运行。

I found a similar question。但是,建议的解决方案并没有解决我的问题。

我有一种预感,这是因为在 Popup 中使用了 ItemsControl,但我不明白为什么会这样,而且只有第一项。

有什么建议吗?

编辑:

Collection 在单独的单例中更新 class。在初始化我的 View 和 ViewModel 时,我创建了一个本地 Collection 引用单例中的那个。我可以确认 Collection 中没有添加重复项,并且它的行为正确。

这是一些示例代码:

XAML:

<Popup IsOpen="{Binding ShowNotifications, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
       StaysOpen="True"
       AllowsTransparency="True">

    <ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">

        <ItemsControl ItemsSource="{Binding AlarmNotifications}">

            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>

                    <StackPanel/>

                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>

            <ItemsControl.ItemTemplate>
                <DataTemplate>

                     <TextBlock Text="{Binding Exception.Message}"/>

                </DataTemplate>
            </ItemsControl.ItemTemplate>

        </ItemsControl>

    </ScrollViewer>

</Popup>

C#View-Model:

public ManagerClass Manager { get; set; }

public ObservableCollection<AlarmRegistry> AlarmNotifications { get; set; }

public bool ShowAlarmNotifications => AlarmNotifications.Any();

protected MainViewModel()
    {
        Manager = ManagerClass.Instance;

        AlarmNotifications = Manager.AlarmNotifications;

        AlarmNotifications.CollectionChanged += (sender, args) =>
        {
            OnPropertyChanged(nameof(ShowAlarmNotifications));
        };
    }

更新:

我发现了两种纠正重复的方法,涉及在添加第一个项目之前打开弹出窗口:

  1. 删除 Popup.IsOpen 绑定并在 XAML 中将其设置为 true。
  2. 正在将 ShowNotifications 的默认值设置为 true。

这些方法会导致应用程序在弹出窗口打开的情况下启动,这是一种不受欢迎的行为。但是,这会阻止 ItemsControl 复制第一个添加的项目。如果在添加第一项之前再次关闭 Popup,则不会发生重复。

现在我正在寻找一种方法,使弹出窗口在 start-up 处保持关闭,而无需重复第一项。一种方法是试图欺骗 Popup 使其在之后立即打开和关闭。

如果您知道为什么会发生这种情况,或者如何应对,请告诉我。

如果在将第一项添加到集合之前未打开弹出窗口,则会发生重复。

为了更正问题,需要执行三个步骤:

  1. 添加一个setter和ShowAlarmNotifications 属性以便可以直接设置并更新用法:

    private bool _showAlarmNotifications;
    
    
    public bool ShowAlarmNotifications
    {
        get => _showAlarmNotifications;
        set
        {
            _showAlarmNotifications = value;
            OnPropertyChanged();
        }
    }
    
    
    AlarmNotifications.CollectionChanged += (sender, args) =>
    {
        ShowAlarmNotifications = AlarmNotifications.Any();
    };
    
  2. 为视图创建一个Loaded事件并将ShowAlarmNotifications设置为true:

    private void View_OnLoaded(object sender, RoutedEventArgs e)
    {
        if (DataContext is ViewModel vm)
            vm.ShowAlarmNotifications = true;
    }
    
  3. 为 Popup 创建一个 Loaded 事件并将 ShowAlarmNotifications 设置为 false:

    private void Popup_OnLoaded(object sender, RoutedEventArgs e)
    {
        if (DataContext is ViewModel vm)
            vm.ShowAlarmNotifications = false;
    }
    

ItemsControl 不再重复第一个条目并且 Popup 在应用程序启动时未打开。

这是一个混乱的解决方案,仍然没有解释为什么会发生重复,但它确实满足要求。

我最近 运行 遇到了同样的问题。我按顺序 AllowsTransparency="True" IsOpen="True" 修复了它。出于某种原因,如果您首先指定 IsOpen,则 t运行sparency 不起作用。另请注意 IsOpen 设置为始终为真。这解决了我的重复问题和 t运行sparency 问题。希望有所帮助。

<Popup AllowsTransparency="True" IsOpen="True">
    <!--your content goes here-->
</Popup>