涉及多边形的 Silverlight ListBox - 滚动时出现异常和失败
目前,我的应用程序中有两个列表框,它们的功能非常相似。问题是一个可以正常工作,而另一个则不能。显示问题的是这个:
<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>
此列表框 ItemsSource 绑定到此类对象的 ObservableCollection:
public class ShapeEncoding
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
private PointCollection shape;
public PointCollection Shape
{
get { return shape; }
set { shape = value;}
}
private int index;
public int Index
{
get { return index; }
set { index = value; }
}
public ShapeEncoding(string n, Polygon p, int i)
{
name = n;
shape = new PointCollection();
foreach (Point pt in p.Points)
{
shape.Add(new Point(pt.X, pt.Y));
}
index = i;
}
}
这两个列表框之间的区别在于,工作的列表框绑定到 Color-Property,而错误的列表框绑定到PointCollection 属性。
ListBox 最初正确绑定了 PointCollection,并且 Polygons 按预期显示。但是,当列表框向下滚动然后再次向上滚动时,先前不在视图中的项目将不会出现,并且每个无法显示的项目都会生成错误。 错误和堆栈跟踪是这样的:
值未落在预期范围内。
在 MS.Internal.XcpImports.CheckHResult(UInt32 小时) 在 MS.Internal.XcpImports.SetValue(IManagedPeerBase obj, DependencyProperty 属性, DependencyObject doh) 在 MS.Internal.XcpImports.SetValue(IManagedPeerBase doh,DependencyProperty 属性,对象 obj) 在 System.Windows.DependencyObject.SetObjectValueToCore(DependencyProperty dp,对象>值) 在 System.Windows.DependencyObject.SetEffectiveValue(DependencyProperty 属性,EffectiveValueEntry& newEntry,对象 newValue) 在 System.Windows.DependencyObject.UpdateEffectiveValue(DependencyProperty 属性、EffectiveValueEntry oldEntry、EffectiveValueEntry& newEntry、ValueOperation 操作) 在 System.Windows.DependencyObject.RefreshExpression(DependencyProperty dp) 在 System.Windows.Data.BindingExpression.SendDataToTarget() 在 System.Windows.Data.BindingExpression.SourceAcquired() 在 System.Windows.Data.BindingExpression.System.Windows.IDataContextChangedListener.OnDataCont>extChanged(对象发送者,DataContextChangedEventArgs e) 在 System.Windows.Data.BindingExpression.DataContextChanged(对象发送者,DataContextChangedEventArgs e) 在 System.Windows.FrameworkElement.OnDataContextChanged(DataContextChangedEventArgs e) 在 System.Windows.FrameworkElement.OnAncestorDataContextChanged(DataContextChangedEventArgs e) 在 System.Windows.FrameworkElement.NotifyDataContextChanged(DataContextChangedEventArgs > e) 在 System.Windows.FrameworkElement.OnTreeParentUpdated(DependencyObject newParent,布尔 bIsNewParentAlive) 在System.Windows.DependencyObject.UpdateTreeParent(IManagedPeer oldParent,IManagedPeer newParent,布尔bIsNewParentAlive,布尔keepReferenceToParent) 在MS.Internal.FrameworkCallbacks.ManagedPeerTreeUpdate(IntPtr oldParentElement,IntPtr&gt;parentElement,IntPtr childElement,字节bIsParentAlive,字节bKeepReferenceToParent,字节&gt;bCanCreateParent)
我怀疑发生了什么。在创建此应用程序的过程中,我意识到 Silverlight 中的 PointCollections 不能在多边形之间共享。那么,当列表框获取视图外的项目时,是否有可能尝试使用相同的 PointCollection 在列表中创建一个新项目,从而导致错误和失败?
如果是这种情况,我不确定解决它的最佳方法是什么。有什么办法可以让 ListBox 不必首先取回 Items 吗?
I currently have two ListBoxes in my application which function in a very similar manner. The problem is that one works properly, and the other does not. The one which displays the issue is this one:
<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>
This Listboxs ItemsSource is bound to an ObservableCollection of objects of this class:
public class ShapeEncoding
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
private PointCollection shape;
public PointCollection Shape
{
get { return shape; }
set { shape = value;}
}
private int index;
public int Index
{
get { return index; }
set { index = value; }
}
public ShapeEncoding(string n, Polygon p, int i)
{
name = n;
shape = new PointCollection();
foreach (Point pt in p.Points)
{
shape.Add(new Point(pt.X, pt.Y));
}
index = i;
}
}
The difference between the two Listboxes is that the working one is bound to a Color-Property, and the erroneous one is bound to a PointCollection-Property.
The ListBox binds the PointCollection properly initally, and the Polygons appear as intended. However, when the ListBox is scrolled down, and then up again, the previously out-of-view items will not appear and errors are generated for each of the items which fail to be displayed.
The Error and Stacktrace is this:
Value does not fall within the expected range.
at MS.Internal.XcpImports.CheckHResult(UInt32 hr)
at MS.Internal.XcpImports.SetValue(IManagedPeerBase obj, DependencyProperty property, DependencyObject doh)
at MS.Internal.XcpImports.SetValue(IManagedPeerBase doh, DependencyProperty property, Object obj)
at System.Windows.DependencyObject.SetObjectValueToCore(DependencyProperty dp, Object >value)
at System.Windows.DependencyObject.SetEffectiveValue(DependencyProperty property, EffectiveValueEntry& newEntry, Object newValue)
at System.Windows.DependencyObject.UpdateEffectiveValue(DependencyProperty property, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, ValueOperation operation)
at System.Windows.DependencyObject.RefreshExpression(DependencyProperty dp)
at System.Windows.Data.BindingExpression.SendDataToTarget()
at System.Windows.Data.BindingExpression.SourceAcquired()
at System.Windows.Data.BindingExpression.System.Windows.IDataContextChangedListener.OnDataCont>extChanged(Object sender, DataContextChangedEventArgs e)
at System.Windows.Data.BindingExpression.DataContextChanged(Object sender, DataContextChangedEventArgs e)
at System.Windows.FrameworkElement.OnDataContextChanged(DataContextChangedEventArgs e)
at System.Windows.FrameworkElement.OnAncestorDataContextChanged(DataContextChangedEventArgs e)
at System.Windows.FrameworkElement.NotifyDataContextChanged(DataContextChangedEventArgs >e)
at System.Windows.FrameworkElement.OnTreeParentUpdated(DependencyObject newParent, Boolean bIsNewParentAlive)
at System.Windows.DependencyObject.UpdateTreeParent(IManagedPeer oldParent, IManagedPeer newParent, Boolean bIsNewParentAlive, Boolean keepReferenceToParent)
at MS.Internal.FrameworkCallbacks.ManagedPeerTreeUpdate(IntPtr oldParentElement, IntPtr >parentElement, IntPtr childElement, Byte bIsParentAlive, Byte bKeepReferenceToParent, Byte >bCanCreateParent)
I have a suspicion as to what is going on. I have become aware during the course of creating this application that PointCollections in Silverlight are not sharable between Polygons. So is it possible that when the Listbox is fetching the out-of-view items, it attempts to create a new Item in the list with the same PointCollection, which in turn causes the error and failure?
If this is the case, I'm not sure what the best way to resolve it would be. It there any way to keep the ListBox from having to fetch back the Items in the first place?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
答案很简单.. 不要“绑定”,也不使用任何东西作为从
PresentationFrameworkCollection
继承的数据...逻辑很简单 - DataBinding 必须“绑定”到数据。 ..
不要使用
PointCollection
,而是使用List
并将这些点转换为“转换器”中的PointCollection
,然后像这样绑定它...
记住。从
PresentationFrameworkCollection
继承的所有内容都是 Silverlight UI 的一部分...请勿将其用作数据...Well the answer is very easy.. do not "bind" and do not use nothing as data that inherited from
PresentationFrameworkCollection<T>
...Logic is simple - DataBinding have to "bind" to data...
Instead of using
PointCollection
useList<Points>
and convert those points into thePointCollection
in the "converter"and then bind it like this...
Just remember. Everithing that inherited from
PresentationFrameworkCollection<T>
is part of Silverlight UI... do not use it as data...