У меня есть UserControl, который представляет собой ListView с Canvas в качестве ItemsPanel. ItemsSource объекта ListView связан с CollectionViewSource, а его свойство Source связано с ObservableCollection . DeviceItem - это пользовательский класс, который, помимо прочего, содержит координаты X / Y ListViewItem / DeviceItem, который сериализуется, когда пользователь хочет сохранить свою работу. В PreviewMouseDown и PreviewTouchDown я проверяю элемент ListViewItem, по которому щелкают / касаются, чтобы убедиться, что содержимое ListViewItem является DeviceItem, так что, когда пользователь перемещал его по экрану, программное обеспечение может обновлять координаты в DeviceItem. Это работает в 99% случаев, но я сталкиваюсь с проблемой (иногда) после того, как пользователь удаляет элементы из коллекции, а затем добавляет новые элементы. После удаления / добавления, когда пользователь щелкает / касается ListViewItem, его Контент имеет тип MS.Internal.NamedObject, и в этом случае я не могу воздействовать на элемент. Я уверен, что стоит упомянуть, что пользователь добавляет / удаляет из отдельного элемента управления в другом окне, которое связано с той же коллекцией в нашей модели данных (ObservableCollection ).
В настоящее время пользователь должен закрыть и снова открыть программное обеспечение, когда это произойдет. Я пытаюсь найти способ восстановления без перезапуска программного обеспечения.
<UserControl.Resources>
<Style x:Key="CanvasStyle" TargetType="{x:Type Canvas}">
<EventSetter Event="Loaded" Handler="Canvas_Loaded"/>
</Style>
<CollectionViewSource Source="{Binding DiagramCollection}" x:Key="radioPacksDataView" />
</UserControl.Resources>
<Grid>
<ListView Name="listBoxDevices"
Background="Transparent"
BorderThickness="0"
Stylus.IsPressAndHoldEnabled ="False"
ItemsSource="{Binding Source={StaticResource radioPacksDataView}}"
PreviewMouseMove="ListBox_PreviewMouseMove"
PreviewMouseDown="ListBox_PreviewMouseDown"
PreviewMouseUp="ListBox_PreviewMouseUp"
PreviewTouchDown="ListBox_PreviewTouchDown"
PreviewTouchMove="ListBox_PreviewTouchMove"
PreviewTouchUp="ListBox_PreviewTouchUp"
SnapsToDevicePixels="True"
IsHitTestVisible="{Binding AccessRights, ConverterParameter=Unlocked, Converter={StaticResource enumBooleanConverter}, Source={x:Static appData:Globals.CurrentUser}}"
VirtualizingPanel.IsVirtualizing="False"
IsSynchronizedWithCurrentItem="False">
<ListView.Style>
<Style>
<Setter Property="ItemsControl.ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<Canvas Style="{DynamicResource CanvasStyle}"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=window, Path=IconStyle}" Value="0">
<Setter Property="ListView.ItemContainerStyle" Value="{DynamicResource MultiDeviceItemContainerStyle}" />
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=window, Path=IconStyle}" Value="1">
<Setter Property="ListView.ItemContainerStyle" Value="{DynamicResource MultiDeviceItemContainerStyleV2}" />
</DataTrigger>
</Style.Triggers>
</Style>
</ListView.Style>
<ListView.LayoutTransform>
<ScaleTransform CenterX="0"
CenterY="0"
ScaleX="{Binding ZoomScale}"
ScaleY="{Binding ZoomScale}"/>
</ListView.LayoutTransform>
</ListView>
</Grid>
А затем в коде позади
private void ListBox_PreviewMouseDown(object sender, MouseEventArgs e)
{
if (m_selectedListViewItem == null)
{
m_selectedListViewItem = ItemsControl.ContainerFromElement((ListBox)sender, e.OriginalSource as DependencyObject) as ListViewItem;
//this is the section that fails after removing/adding items, object is typeof(MS.Internal.NamedObject)
if (m_selectedListViewItem.Content.GetType().IsSubclassOf(typeof(DeviceItem)))
{
m_selectedDeviceItem = m_selectedListViewItem.Content as DeviceItem;
}
}
}