C# 涉及多边形的Silverlight列表框-滚动时出现异常和失败
目前,我的应用程序中有两个列表框,它们的功能非常相似。问题是一个能正常工作,另一个不能。显示问题的是以下问题:C# 涉及多边形的Silverlight列表框-滚动时出现异常和失败,c#,xaml,silverlight-4.0,C#,Xaml,Silverlight 4.0,目前,我的应用程序中有两个列表框,它们的功能非常相似。问题是一个能正常工作,另一个不能。显示问题的是以下问题: <ListBox Grid.Row="2" Margin="0,35,10,5" Name="shapeEncodingListBox" HorizontalAlignment="Right" Width="225" Style="{StaticResource EncodingListBoxStyle}" BindingValidationError="shapeEncodi
<ListBox Grid.Row="2" Margin="0,35,10,5" Name="shapeEncodingListBox" HorizontalAlignment="Right" Width="225" Style="{StaticResource EncodingListBoxStyle}" BindingValidationError="shapeEncodingListBox_BindingValidationError">
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu>
<toolkit:MenuItem Header="Show Items" Click="MenuItem_Click" />
<toolkit:MenuItem Header="Hide Items" Click="MenuItem_Click_1"/>
<toolkit:Separator/>
<toolkit:MenuItem Header="Isolate Items" Click="MenuItem_Click_2" />
<toolkit:Separator/>
<toolkit:MenuItem Header="Select Items" Click="MenuItem_Click_3" />
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Style="{StaticResource EncodingListBoxItemPanelStyle}">
<Polygon Points="{Binding Shape}" Style="{StaticResource EncodingListBoxItemShapeIndicatorStyle}"/>
<TextBlock x:Name="encodeShapePanelLegend" Text="{Binding Name}" Style="{StaticResource EncodingListBoxItemTextStyle}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
两个列表框之间的区别在于,工作列表框绑定到颜色属性,而错误列表框绑定到PointCollection属性
ListBox在初始阶段正确绑定PointCollection,多边形将按预期显示。但是,当列表框向下滚动,然后再次向上滚动时,以前不在视图中的项目将不会出现,并且会为无法显示的每个项目生成错误。
错误和堆栈跟踪如下所示:
值不在预期范围内
在MS.Internal.XcpImports.CheckHResultUInt32小时
在MS.Internal.XcpImports.SetValueIManagedPeerBase对象中,DependencyProperty属性,DependencyObject doh
在MS.Internal.XcpImports.SetValueIManagedPeerBase doh中,DependencyProperty属性,对象对象obj
在System.Windows.DependencyObject.SetObjectValueToCoreDependencyProperty dp中,对象>值
在System.Windows.DependencyObject.SetEffectiveValueDependencyProperty属性、EffectiveValueEntry和newEntry、Object newValue中
在System.Windows.DependencyObject.UpdateEffectiveValueDependencyProperty属性、EffectiveValueEntry oldEntry、EffectiveValueEntry和newEntry、ValueOperation操作中
位于System.Windows.DependencyObject.RefreshExpressionDependencyProperty dp
位于System.Windows.Data.BindingExpression.SendDataToTarget
在System.Windows.Data.BindingExpression.SourceAcquired上
在System.Windows.Data.BindingExpression.System.Windows.IDataContextChangedListener.OnDataCont>extChangedObject发送方,DataContextChangedEventArgs e
在System.Windows.Data.BindingExpression.DataContextChangedObject发送方,DataContextChangedEventArgs e
位于System.Windows.FrameworkElement.OnDataContextChangedDataContextChangedEventArgs e
位于System.Windows.FrameworkElement.OnAncestorDataContextChangedDataContextChangedEventArgs e
在System.Windows.FrameworkElement.NotifyDataContextChangedDataContextChangedEventArgs>e
位于System.Windows.FrameworkElement.OnTreeparentUpdatedPendencyObject newParent,布尔值为bIsNewParentAlive
在System.Windows.DependencyObject.UpdateTreeParentIManagedPeer oldParent、IManagedPeer newParent、Boolean bIsNewParentAlive、Boolean keepReferenceToParent中
在MS.Internal.FrameworkCallbacks.ManagedPeerTreeUpdateIntPtr oldParentElement、IntPtr>parentElement、IntPtr childElement、Byte bIsParentAlive、Byte bKeepReferenceToParent、Byte>bCanCreateParent
我怀疑发生了什么事。在创建此应用程序的过程中,我意识到Silverlight中的点集合不能在多边形之间共享。那么,当Listbox获取视图外的项时,它是否可能尝试在列表中使用相同的PointCollection创建一个新项,从而导致错误和失败
如果是这样的话,我不确定最好的解决办法是什么。有什么办法可以让列表框不必首先取回项目吗?答案很简单。。不要绑定,也不要将任何内容用作从PresentationFrameworkCollection继承的数据 逻辑很简单-数据绑定必须绑定到数据 不要使用PointCollection,而是使用List并将这些点转换为转换器中的PointCollection
public class PointsToPointsCollectionsConverter: IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var points = value as List<Point>;
if (points != null)
{
var pc = new PointCollection();
foreach (var point in points)
{
pc.Add(point);
}
return pc;
}
else return null;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
然后像这样绑起来
<UserControl x:Class="SilverlightApplication2.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:local="clr-namespace:SilverlightApplication2"
d:DesignHeight="300" d:DesignWidth="400">
<UserControl.Resources>
<local:PointsToPointsCollectionsConverter x:Key="ptpc"/>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<ListBox x:Name="testListBox1" Width="100" Height="100">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<Polygon Fill="Red"
Points="{Binding Points, Converter={StaticResource ptpc}}"/>
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
记住。从PresentationFrameworkCollection继承的所有内容都是Silverlight UI的一部分。。。不要将其用作数据
<UserControl x:Class="SilverlightApplication2.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:local="clr-namespace:SilverlightApplication2"
d:DesignHeight="300" d:DesignWidth="400">
<UserControl.Resources>
<local:PointsToPointsCollectionsConverter x:Key="ptpc"/>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<ListBox x:Name="testListBox1" Width="100" Height="100">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<Polygon Fill="Red"
Points="{Binding Points, Converter={StaticResource ptpc}}"/>
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>