Domanda

Al momento sto implementando una classe chiamata SelectionBorder in WPF. E 'derivato dalla classe Shape.

Si presenta sostanzialmente in questo modo:

public class SelectionBorder : Shape
{
   public Point StartPoint {get; set;}
   public PointCollection Points {get; set;}

   public double StrokeLength {get; set;}

   protected override Geometry DefiningGeometry{
       get{
           //Magic!
       }
   }

}

il punto di inizio e punti di proprietà determinano gli angoli del confine. Il confine è un tipico bordo linea accarezzato (un tratto nero, un colpo invisibile così: - - - -)

Il problema che ho ora è che, poiché i punti d'angolo sono liberamente choosable è abbastanza comune che il conteggio dei colpi (ovvero tratti neri e invisibili) non è nemmeno (in realtà nemmeno un numero intero) e quindi il primo aspetto ictus più lungo degli altri (visibile nella foto). Questo forse non sembra essere un grosso problema, ma poi voglio animare il confine in modo che i colpi cerchio intorno al contenuto. Nel fare questa animazione il piccolo difetto nella visione statica diventa chiaramente visibile e, a mio parere è molto preoccupante.

alt text http://img14.imageshack.us/img14/2874/selectionborder .png

Il problema è che ho cercato di stabilire uno StrokeLength che ottiene più vicino possibile al StrokeLength originale possibile e crea un numero di colpi. Tuttavia il problema che ho incontrato è che WPF (ovviamente) non è in grado di visualizzare l'intera precisione di uno StrokeLength doppia decimale e quindi il numero di corse risultante non è uniforme, ancora una volta.

C'è una soluzione per questo problema? Cosa probabilmente si dispone di un'altra soluzione per il mio problema?

Grazie in anticipo!

EDIT: ho riprovato e rivisto il codice dopo una piccola pausa per il fitness oggi e dopo tutto succede solo su molto grande StrokeLengths. Ho intenzione di utilizzare StrokeLengths del 2 dove la piccola animazione salto importa molto meno di quanto inizialmente pensato.

È stato utile?

Soluzione 2

ho appena trovato un modo che rende modo più semplice per creare un tale SelectionBorder animato.

Invece di creare l'animazione muovendo un AnimationPoint auto-creato attraverso l'animazione Ho appena animato la proprietà StrokeDashOffset nativamente fornito dalla classe Shape e l'impostazione del StrokeDashArray per definire la StrokeLength.

Si sarebbe simile a questa in XAML:

<namespace:SelectionBorder StrokeDashArray="2" AnimationDuration="0:0:1" Stroke="Black" />

La classe si presenta così:

public class SelectionBorder : Shape
{
    private DoubleAnimation m_Animation;
    private bool m_AnimationStarted;

    public SelectionBorder()
    {
        IsVisibleChanged += OnIsVisibleChanged;
    }

    protected void OnIsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        if (Visibility == Visibility.Visible)
        {
            StartAnimation();
        }
        else
        {
            StopAnimation();
        }
    }

    public void StartAnimation()
    {
        if (m_AnimationStarted)
            return;

        if (m_Animation == null)
        {
            m_Animation = CreateAnimation();
        }

        BeginAnimation(StrokeDashOffsetProperty, m_Animation);
        m_AnimationStarted = true;
    }

    protected virtual DoubleAnimation CreateAnimation()
    {
        DoubleAnimation animation = new DoubleAnimation();
        animation.From = 0;
        if (StrokeDashArray.Count == 0)
            animation.To = 4;
        else
            animation.To = StrokeDashArray.First() * 2;
        animation.Duration = AnimationDuration;
        animation.RepeatBehavior = RepeatBehavior.Forever;
        return animation;
    }

    public void StopAnimation()
    {
        if (m_AnimationStarted)
        {
            BeginAnimation(StrokeDashOffsetProperty, null);
            m_AnimationStarted = false;
        }
    }

    #region Dependency Properties

    public Duration AnimationDuration
    {
        get { return (Duration)GetValue(AnimationDurationProperty); }
        set { SetValue(AnimationDurationProperty, value); }
    }

    public static readonly DependencyProperty AnimationDurationProperty =
        DependencyProperty.Register("AnimationDuration", typeof(Duration), typeof(SelectionBorder), new UIPropertyMetadata(new Duration(TimeSpan.FromSeconds(0.5))));


    #endregion Dependency Properties

    protected override Geometry DefiningGeometry
    {
        get
        {
            double width = (double.IsNaN(Width)) ? ((Panel)Parent).ActualWidth : Width;
            double height = (double.IsNaN(Height)) ? ((Panel)Parent).ActualHeight : Height;

            RectangleGeometry geometry = new RectangleGeometry(new Rect(0, 0, width, height));

            return geometry;
        }
    }
}

Altri suggerimenti

Si potrebbe fare più di un angolo "un-abbinato" al riguardo. Ad esempio, invece di avere un punto sia la "sorgente" e "destinazione" dei trattini animati, si poteva scegliere 2 punti. Uno potrebbe essere la "fonte", trattini apparendo a marciare a partire da esso in 2 direzioni, e un altro punto la "destinazione", dove convergono i trattini e scompaiono.

GIMP, per esempio, anima selezione linee tratteggiate in questo modo e sembra selezionare un punto più vicino alla parte inferiore sinistra per la "sorgente" e un punto più vicino alla parte superiore destra per la "destinazione".

Si potrebbe trovare un qualche altro schema, pure.

Basta ricordare che, mentre può sembrare inquietante a te, maggior parte degli utenti non si cura.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top