【发布时间】:2018-09-06 12:01:33
【问题描述】:
我在Popup 中有一个ItemsControl 和一个ObservableCollection,我将其简称为“集合”,绑定到ItemsControl.ItemsSource 属性。
ItemsControl 将始终复制添加到集合中的第一个项目。然后ItemsControl 会正确处理之后添加的每个项目。
- 没有发生跨线程操作。
- 集合仅在一个地方更新,每个项目创建一个调用。
-
ItemsControl.ItemsPanel是一个没有虚拟化的StackPanel。
I found a similar question。但是,建议的解决方案并没有解决我的问题。
我有一种预感,这是由于在 Popup 中使用了 ItemsControl,但我无法弄清楚为什么会发生这种情况,并且只能使用第一项。
有什么建议吗?
编辑:
集合在单独的单例类中更新。在初始化我的视图和视图模型时,我创建了一个本地集合,引用了单例中的集合。我可以确认没有重复的项目添加到集合中,并且它的行为正确。
这里是一些示例代码:
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# 视图模型:
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));
};
}
更新:
我发现了两种纠正重复的方法,即在添加第一项之前打开弹出窗口:
- 删除
Popup.IsOpen绑定并在 XAML 中将其设置为 true。 - 将
ShowNotifications的默认值设置为true。
这些方法会导致应用程序在弹出窗口打开时启动,这是一种不受欢迎的行为。但是,这会阻止 ItemsControl 复制添加的第一个项目。如果在添加第一项之前再次关闭 Popup,则不会发生重复。
现在我正在寻找一种方法来保持弹出窗口在启动时关闭,而不会重复第一个项目。一种方法是试图诱使弹出窗口在之后立即打开和关闭。
如果您知道为什么会发生这种情况,或者如何应对,请告诉我。
【问题讨论】:
-
“ItemsControl 将始终复制添加到集合中的第一个项目。”...我从未在手册中阅读过它,它究竟是什么意思?添加所需的数据以使其清晰!
-
什么不清楚?我将单个项目添加到绑定到 ItemsControl 的 ObservableCollection 中,并且该项目在 UI 中显示两次。这种情况始终如一,但仅适用于会话中添加的第一项。
-
所以你说当你在有界集合上添加一个新项目时,弹出窗口(我想是组合框的)在两行中向你显示该项目。如果是这样,某处应该有一个错误。发布示例代码以重现此行为以获得帮助并找到更正
-
我希望某处存在错误,但由于代码如此简单,我无法理解为什么会发生这种情况。除非弹出窗口涉及一些奇怪的行为,正如我在类似问题的链接中所指出的那样。
-
默认情况下,BindingMode 是 OneTime,您可能会看到将其设置为 OneWay 时会发生什么,它会在集合更改时刷新绑定的 UI。
标签: wpf xaml itemscontrol