首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >创建SelectionBorder:通过小数点舍入?

创建SelectionBorder:通过小数点舍入?
EN

Stack Overflow用户
提问于 2009-08-19 12:48:12
回答 2查看 225关注 0票数 2

我目前正在用WPF实现一个名为SelectionBorder的类。它是从Shape类派生的。

它基本上看起来像这样:

代码语言:javascript
复制
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属性确定边框的角点。边框是典型的描边线条边框(一个黑色的描边,一个看不见的描边:-- -)

我现在的问题是,由于角点是可自由选择的,因此笔画(即黑色和不可见的笔画)的计数不是偶数(实际上甚至不是整数)是很常见的,因此第一个笔画看起来比其他笔画(在图片中可见)要长。这可能看起来不是什么大问题,但我稍后想要使边框具有动画效果,以便笔画环绕内容。当做这个动画时,静态视图中的小缺陷变得清晰可见,在我看来,这是非常令人不安的。

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

问题是,我试图确定一个尽可能接近原始StrokeLength的StrokeLength,并创建偶数个笔画。然而,我遇到的问题是,WPF (显然)不能显示双十进制StrokeLength的整个精度,因此结果笔画数再次不均匀。

是否有解决此问题的方法?你有没有别的办法来解决我的问题?

提前感谢!

编辑:今天,为了适应,我重新测试和审查了代码,毕竟这只发生在非常大的StrokeLengths上。我计划使用StrokeLengths of 2,其中的小动画跳跃比我最初想象的要小得多。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2009-08-24 10:55:23

我刚刚找到了一种方法,可以让创建这样一个动画SelectionBorder变得更容易。

我并不是通过在动画中移动自创建的AnimationPoint来创建动画,而是只对Shape类原生提供的StrokeDashOffset属性进行动画处理,并设置StrokeDashArray来定义StrokeLength。

在XAML中,它看起来像这样:

代码语言:javascript
复制
<namespace:SelectionBorder StrokeDashArray="2" AnimationDuration="0:0:1" Stroke="Black" />

这个类看起来像这样:

代码语言:javascript
复制
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;
        }
    }
}
票数 0
EN

Stack Overflow用户

发布于 2009-08-19 17:15:38

在这一点上,你可能会使不止一个角落“不匹配”。例如,您可以选择2个点,而不是将一个点作为动画虚线的“源”和“目标”。一个是“源”,破折号似乎在两个方向上远离它,另一个点是“目的地”,破折号在那里汇聚和消失。

例如,GIMP以这种方式对选择虚线进行动画处理,并且似乎为“源”选择了最靠近左下角的点,为“目标”选择了最接近右上角的点。

你也可以想出一些其他的方案。

只需记住,虽然它看起来可能会让你感到困扰,但大多数用户并不会在意。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1299706

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档