弹出窗口中的ItemsControl复制添加的第一个项目

时间:2018-09-06 12:01:33

标签: wpf xaml itemscontrol

我在ItemsControl内有一个Popup的{​​{1}},我将其简称为“集合”,绑定到ObservableCollection属性。

ItemsControl.ItemsSource将始终复制添加到集合中的第一项。然后,ItemsControl对于此后添加的每个项目都正确运行。

  • 没有发生跨线程操作。
  • 该收藏集仅在一个地方更新,每创建一个项目都会调用一次。
  • ItemsControlItemsControl.ItemsPanel,没有虚拟化。

I found a similar question。但是,提出的解决方案并不能解决我的问题。

我有一种预感,这是由于在StackPanel中使用了ItemsControl,但我无法弄清楚为什么会发生这种情况,而且仅凭第一个项目就可以知道。

有什么建议吗?

编辑:

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

以下是一些示例代码:

XAML:

Popup

C#视图模型

<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>

更新:

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

  1. 在XAML中删除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)); }; } 绑定并将其设置为true。
  2. Popup.IsOpen的默认值设置为true。

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

现在,我正在寻找一种方法,在启动时使弹出窗口保持关闭状态,而不会重复第一项。一种方法是尝试诱骗Popup之后立即打开和关闭。

如果您知道这种情况的发生原因或应对方法,请告诉我。

2 个答案:

答案 0 :(得分:1)

我最近遇到了同样的问题。我通过按AllowsTransparency="True" IsOpen="True"的顺序进行修复。由于某些原因,如果您先指定IsOpen,则透明度将不起作用。另请注意,IsOpen设置为始终为true。这解决了我的重复问题和透明度问题。希望能有所帮助。

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

答案 1 :(得分:0)

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

要纠正此问题,需要执行三个步骤:

  1. 将设置器添加到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. 为弹出窗口创建一个Loaded事件,并将ShowAlarmNotifications设置为false

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

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

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