There is a canvas element with 10 children (polygons). There is a number in my code from 1 to 10.
I'd like to draw the first N开发者_如何学C elements from the children elements, base on my number.
It would be the best solution to do this from XAML with a minimum code-behind like this:
...
MyCanvas.N = 5;
...
For this purpose I generally use an expression binding class I wrote called "edf:Visibility" that allows me to do this:
<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>
The same thing can be done using a standard binding and a converter as follows:
...
<Setter Property="Visibility"
Value="{Binding RelativeSource={RelativeSource Self},
Converter={x:Static AlternationIndexComparer.Instance}}" />
...
Of course in this case you have to write the converter yourself.
If your polygons are all fixed width or height and evenly spaced, an easy way to implement this with no code is to use a clipping geometry and transform its width (or height) by a factor of N to cause it to show only N polygons. The XAML for the clipping geometry has a transform like this:
<PathGeometry>
<PathGeometry.Transform>
<ScaleTransform ScaleX="{Binding N}" />
</PathGeometry.Transform>
...
</PathGeometry>
From your description of the problem this doesn't appear to apply in your case.
A general solution is to create an attached property with this functionality which can simply be used like this:
<Canvas local:MyAttachedProperties.ChildrenVisible="{Binding N}">
...
</Canvas>
in this case you have to create the ChildrenVisible property, but you only have to code it once and it will work for any panel (not just canvas). Here is the technique in detail:
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;
}
I hope, I understood your question correctly:
All children you add to the canvas will be drawn. To solve your problem you will have to a) add only the children you want to draw or b) derive from the Canvas-class and override the OnRender method.
精彩评论