Popup 中的 ItemsControl 复制添加的第一个项目
ItemsControl inside Popup duplicates the first item added
我在 Popup
中有一个 ItemsControl
和一个 ObservableCollection
,我简称为 'Collection',绑定到 ItemsControl.ItemsSource
属性.
ItemsControl
将始终复制第一个添加到 Collection 的项目。 ItemsControl
之后添加的每个项目都会正确运行。
- 没有 cross-thread 操作发生。
- Collection 仅更新一处,每创建一个项目调用一次。
ItemsControl.ItemsPanel
是没有虚拟化的 StackPanel
。
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));
};
}
更新:
我发现了两种纠正重复的方法,涉及在添加第一个项目之前打开弹出窗口:
- 删除
Popup.IsOpen
绑定并在 XAML 中将其设置为 true。
- 正在将
ShowNotifications
的默认值设置为 true。
这些方法会导致应用程序在弹出窗口打开的情况下启动,这是一种不受欢迎的行为。但是,这会阻止 ItemsControl 复制第一个添加的项目。如果在添加第一项之前再次关闭 Popup,则不会发生重复。
现在我正在寻找一种方法,使弹出窗口在 start-up 处保持关闭,而无需重复第一项。一种方法是试图欺骗 Popup 使其在之后立即打开和关闭。
如果您知道为什么会发生这种情况,或者如何应对,请告诉我。
如果在将第一项添加到集合之前未打开弹出窗口,则会发生重复。
为了更正问题,需要执行三个步骤:
添加一个setter和ShowAlarmNotifications
属性以便可以直接设置并更新用法:
private bool _showAlarmNotifications;
public bool ShowAlarmNotifications
{
get => _showAlarmNotifications;
set
{
_showAlarmNotifications = value;
OnPropertyChanged();
}
}
AlarmNotifications.CollectionChanged += (sender, args) =>
{
ShowAlarmNotifications = AlarmNotifications.Any();
};
为视图创建一个Loaded
事件并将ShowAlarmNotifications
设置为true
:
private void View_OnLoaded(object sender, RoutedEventArgs e)
{
if (DataContext is ViewModel vm)
vm.ShowAlarmNotifications = true;
}
为 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>
我在 Popup
中有一个 ItemsControl
和一个 ObservableCollection
,我简称为 'Collection',绑定到 ItemsControl.ItemsSource
属性.
ItemsControl
将始终复制第一个添加到 Collection 的项目。 ItemsControl
之后添加的每个项目都会正确运行。
- 没有 cross-thread 操作发生。
- Collection 仅更新一处,每创建一个项目调用一次。
ItemsControl.ItemsPanel
是没有虚拟化的StackPanel
。
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));
};
}
更新:
我发现了两种纠正重复的方法,涉及在添加第一个项目之前打开弹出窗口:
- 删除
Popup.IsOpen
绑定并在 XAML 中将其设置为 true。 - 正在将
ShowNotifications
的默认值设置为 true。
这些方法会导致应用程序在弹出窗口打开的情况下启动,这是一种不受欢迎的行为。但是,这会阻止 ItemsControl 复制第一个添加的项目。如果在添加第一项之前再次关闭 Popup,则不会发生重复。
现在我正在寻找一种方法,使弹出窗口在 start-up 处保持关闭,而无需重复第一项。一种方法是试图欺骗 Popup 使其在之后立即打开和关闭。
如果您知道为什么会发生这种情况,或者如何应对,请告诉我。
如果在将第一项添加到集合之前未打开弹出窗口,则会发生重复。
为了更正问题,需要执行三个步骤:
添加一个setter和
ShowAlarmNotifications
属性以便可以直接设置并更新用法:private bool _showAlarmNotifications; public bool ShowAlarmNotifications { get => _showAlarmNotifications; set { _showAlarmNotifications = value; OnPropertyChanged(); } } AlarmNotifications.CollectionChanged += (sender, args) => { ShowAlarmNotifications = AlarmNotifications.Any(); };
为视图创建一个
Loaded
事件并将ShowAlarmNotifications
设置为true
:private void View_OnLoaded(object sender, RoutedEventArgs e) { if (DataContext is ViewModel vm) vm.ShowAlarmNotifications = true; }
为 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>