Для этой цели я обычно использую класс привязки выражений, который я написал, под названием "edf: Visibility", что позволяет мне сделать это:
<ItemsControl ItemsSource="{Binding Polygons}" AlternationCount="1000000">
<ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsPanel>
<ItemContainerStyle>
<Style>
<Setter Property="Visibility"
Value="{edf:Visibility self.AlternationIndex < context.N}" />
</Style>
</ItemContainerStyle>
</ItemsControl>
То же самое можно сделать, используя стандартную привязку и конвертерследующим образом:
...
<Setter Property="Visibility"
Value="{Binding RelativeSource={RelativeSource Self},
Converter={x:Static AlternationIndexComparer.Instance}}" />
...
Конечно, в этом случае вы должны написать конвертер самостоятельно.
Если все полигоны имеют фиксированную ширину или высоту и равномерно распределены, простой способ реализовать этобез кода означает использовать геометрию отсечения и преобразовать ее ширину (или высоту) с коэффициентом N, чтобы он показывал только N полигонов.XAML для геометрии отсечения имеет преобразование, подобное этому:
<PathGeometry>
<PathGeometry.Transform>
<ScaleTransform ScaleX="{Binding N}" />
</PathGeometry.Transform>
...
</PathGeometry>
Из вашего описания проблемы это, кажется, не применимо в вашем случае.
Общее решение состоит в том, чтобы создатьприкрепленное свойство с этой функциональностью, которое можно просто использовать следующим образом:
<Canvas local:MyAttachedProperties.ChildrenVisible="{Binding N}">
...
</Canvas>
, в этом случае вам нужно создать свойство ChildrenVisible, но вам нужно только один раз кодировать его, и оно будет работать для любой панели (не просто холст).Вот техника в деталях:
public class MyAttachedProperties
{
... GetChildrenVisible ... // use propa snippet to implement attached property
... SetChildrenVisible ...
... RegisterAttached("ChildrenVisible", typeof(int), typeof(MyAttachedProperties), new PropertyMetadata
{
DefaultValue = int.MaxValue,
PropertyChangedCallback = (obj, e) =>
{
UpdateVisibility((Panel)obj);
if(((int)e.OldValue)==int.MaxValue)
((UIElement)obj).LayoutUpdated += (obj2, e2) => UpdateVisibility((Panel)obj2);
}
});
static void UpdateVisibility(Panel panel)
{
int n = GetChildrenVisible(panel);
int i = 0;
foreach(var child in panel.Children)
child.Visibility = (i++ < n) ? Visibility.Visible : Visibility.Collapsed;
}