我覆盖listbox的ArrangeOverride方法想要像这样显示itemSource: (我在PrepareContainerForItemOverride方法上收集DependencyObject)
1 2 3 4
5 6 7 8
.....
...... 100
但是当我滚动滚动条时,数组会改变如下:
1
2
3
4
5
......
100个
protected override Size ArrangeOverride(Size finalSize)
{
if (this._ItemsDictionary.Count <= 0)
{
return base.ArrangeOverride(finalSize);
}
base.ArrangeOverride(finalSize);
finalSize = this.MeasureOverride(_availableSize);
double xMemory = 0;
double yMemory = 0;
double maxBoderWidth = 0;
double maxHeight = 0;
foreach (FrameworkElement element in _ItemsDictionary.Values)
{
if (xMemory + element.DesiredSize.Width <= finalSize.Width)
{
element.Arrange(new Rect(xMemory, yMemory, element.DesiredSize.Width, element.DesiredSize.Height));
xMemory += element.DesiredSize.Width;
maxHeight = Math.Max(element.DesiredSize.Height, maxHeight);
}
else
{
yMemory += maxHeight;
maxBoderWidth = Math.Max(maxBoderWidth, xMemory);
xMemory = 0;
maxHeight = 0;
element.Arrange(new Rect(xMemory, yMemory, element.DesiredSize.Width, element.DesiredSize.Height));
xMemory += element.DesiredSize.Width;
maxHeight = Math.Max(element.DesiredSize.Height, maxHeight);
}
}
return finalSize;
}
protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
{
base.PrepareContainerForItemOverride(element, item);
FrameworkElement fElement = element as FrameworkElement;
if (!_ItemsDictionary.ContainsKey(item))
{
_ItemsDictionary.Add(item, fElement);
}
}
答案 0 :(得分:2)
我可能错了。但似乎您的基类是 ItemsPresenter (或者从 ListBox 继承的东西)。这不是一个好的idia。到了每个 ItemsPresenter 拥有它自己的 ItemsPanel ! Silverlight使用此面板来布局项目。因此 ItemsPresenter 无法直接布置自己的项目,只需要 ItemsPanel 面板。
1)我建议你使用 WrapPanel (这是Silverlight SDK的一部分),所以你可以免费使用它,我想这就是你想要的。只需用 WrapPanel 替换ListBox.ItemsPanel属性,你就可以得到你想要的结果
2)如果你想创建自己的pannel,你最好创建一个新类并从Panel
继承它public class SomeNewPanel: Panel
{
protected override System.Windows.Size MeasureOverride(System.Windows.Size availableSize)
{
//you can add here your custom measure logic
return base.MeasureOverride(availableSize);
}
protected override System.Windows.Size ArrangeOverride(System.Windows.Size finalSize)
{
//you can add here your custom arrange logic
return base.ArrangeOverride(finalSize);
}
}
然后像这样在ListBox中使用它。
<Page x:Class="SilverlightApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
<!--Don't forget to add namespace of your newly created panel-->
xmlns:local="clr-namespace:SilverlightApplication1"
Title="MainWindow" Height="350" Width="525">
<Grid>
<ListBox x:Name="listBox1" ItemsSource="{Binding SomeItemSource}">
<!--ItemPanel property set or get Panel that-->
<!--will be used for layouting items-->
<ListBox.ItemsPanel>
<!--Here you and your newly created panle-->
<local:SomeNewPanel/>
</ListBox.ItemsPanel>
</ListBox>
</Grid>
</Page>