2

現在、WPFでSelectionBorderというクラスを実装しています。これは、Shapeクラスから派生しています。

基本的には次のようになります。

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!
       }
   }

}

StartPointプロパティとPointsプロパティは、境界線の角を決定します。境界線は、典型的な線の境界線です(1つの黒い線、そのような1つの見えない線:--------)

私が今抱えている問題は、コーナーポイントが自由に選択できるため、ストロークの数(黒と目に見えないストロークを意味する)が均一ではない(実際には整数でもない)ため、最初のストロークがその他(写真に表示)。これは大したことではないように思われるかもしれませんが、後でストロークがコンテンツの周りを一周するように境界線をアニメーション化したいと思います。このアニメーションを実行すると、静的ビューの小さな欠陥がはっきりと見えるようになり、私の意見では非常に不安になります。

代替テキストhttp://img14.imageshack.us/img14/2874/selectionborder.png

問題は、元のStrokeLengthにできるだけ近くなり、偶数のストロークを作成するStrokeLengthを決定しようとしたことです。ただし、私が遭遇した問題は、WPFが(明らかに)小数点以下2桁のStrokeLengthの全体の精度を表示できないため、結果のストローク数が再び不均一になることです。

この問題の回避策はありますか?私の問題に対する別の解決策はおそらくありますか?

前もって感謝します!

編集:私は今日フィットネスのために少し休憩した後、コードを再テストしてレビューしました、そして結局それは非常に大きなStrokeLengthsでのみ起こります。StrokeLengths 2を使用する予定です。この場合、アニメーションのジャンプは、当初考えていたよりもはるかに重要ではありません。

4

2 に答える 2

1

その点で、複数のコーナーを「不一致」にすることができます。たとえば、1 つのポイントをアニメーション化されたダッシュの「ソース」と「宛先」にする代わりに、2 つのポイントを選択できます。1 つは「ソース」で、ダッシュが 2 方向に離れていくように見えます。もう 1 つは、ダッシュが収束して消える「宛先」です。

たとえば、GIMP はこの方法で選択破線をアニメーション化し、「ソース」の左下に最も近いポイントと「宛先」の右上に最も近いポイントを選択するように見えます。

他のスキームを考え出すこともできます。

あなたには邪魔に見えるかもしれませんが、ほとんどのユーザーは気にしないことを覚えておいてください.

于 2009-08-19T17:15:37.810 に答える
0

このようなアニメーション化された SelectionBorder を簡単に作成できる方法を見つけました。

自己作成した AnimationPoint をアニメーションで移動してアニメーションを作成する代わりに、Shape クラスによってネイティブに提供される StrokeDashOffset プロパティをアニメーション化し、StrokeDashArray を設定して StrokeLength を定義しました。

XAML では次のようになります。

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

クラスは次のようになります。

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;
        }
    }
}
于 2009-08-24T10:55:22.787 に答える