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>