2010-04-08 4 views
1

Il y a un élément canvas avec 10 enfants (polygones). Il y a un nombre dans mon code de 1 à 10.Comment dessiner N premiers éléments?

Je voudrais dessiner les N premiers éléments des éléments enfants, base sur mon numéro.

Ce serait la meilleure solution pour faire de XAML avec un code-behind minimum comme ceci:

... 
MyCanvas.N = 5; 
... 

Répondre

1

A cet effet, j'utilise généralement une expression classe Binding j'ai écrit appelé « edf: visibilité » qui me permet de le faire:

<ItemsControl ItemsSource="{Binding Polygons}" AlternationCount="1000000"> 
    <ItemsPanel> 
    <ItemsPanelTemplate> 
     <Canvas /> 
    </ItemsPanelTemplate> 
    </ItemsPanel> 
    <ItemContainerStyle> 
    <Style> 
     <Setter Property="Visibility" 
       Value="{edf:Visibility self.AlternationIndex &lt; context.N}" /> 
    </Style> 
    </ItemContainerStyle> 
</ItemsControl> 

La même chose peut être fait en utilisant une liaison standard et un convertisseur suit:

... 
     <Setter Property="Visibility" 
       Value="{Binding RelativeSource={RelativeSource Self}, 
         Converter={x:Static AlternationIndexComparer.Instance}}" /> 
... 

Bien sûr, dans ce cas, vous devez écrire le convertisseur vous-même. Si vos polygones sont tous fixes en largeur ou en hauteur et régulièrement espacés, un moyen facile de mettre en œuvre ceci sans code consiste à utiliser une géométrie de découpe et à transformer sa largeur (ou sa hauteur) par un facteur N pour l'afficher seulement N polygones. Le XAML pour la géométrie de découpage a une transformation comme celui-ci:

<PathGeometry> 
    <PathGeometry.Transform> 
    <ScaleTransform ScaleX="{Binding N}" /> 
    </PathGeometry.Transform> 
    ... 
</PathGeometry> 

D'après votre description du problème, cela ne semble pas appliquer dans votre cas.

Une solution générale est de créer une propriété attachée avec cette fonctionnalité qui peut simplement être utilisé comme ceci:

<Canvas local:MyAttachedProperties.ChildrenVisible="{Binding N}"> 
    ... 
</Canvas> 

dans ce cas, vous devez créer la propriété ChildrenVisible, mais vous avez seulement à coder une fois et cela fonctionnera pour n'importe quel panneau (pas seulement la toile). Voici la technique en détail:

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; 
    } 
+0

Merci pour la réponse détaillée. En fait, ils sont uniformément épars et après votre publication je vois que l'écrêtage serait assez bon (je cherchais une solution plus élégante). Au moins, il est facile à mettre en œuvre :) – noober

0

je l'espère, je compris votre question:

Tous les enfants que vous ajoutez à la la toile sera dessinée. Pour résoudre votre problème, vous devrez a) n'ajouter que les enfants que vous voulez dessiner ou b) dériver de la classe Canvas et remplacer la méthode OnRender.

+0

Je voudrais voir, comment cela pourrait être fait dans le style WPF. Quelque chose avec liaison ou déclencheurs. – noober

Questions connexes