none
请问使用DynamicRenderer以后,为什么不动态显示绘制的轨迹? RRS feed

  • 问题

  • 我使用DynamicRenderer绘制轨迹,为什么只显示静态笔画,而动态笔画显示不出来呢?

    例子地址:https://skydrive.live.com/redir.aspx?cid=8f125a6da8d15aee&resid=8F125A6DA8D15AEE!103

    基本代码如下:

    主窗口:

            private void canvas1_MouseDown(object sender, MouseButtonEventArgs e)

            {

                Point pt = e.GetPosition(this.canvas1);

                if (DrawType == 1)

                {

                    CurItem = new NormalPen(this.canvas1);

                    this.canvas1.Children.Add(CurItem);

                    Canvas.SetLeft(CurItem, 0);

                    Canvas.SetTop(CurItem, 0);

                    this.CurItem.RenderSize = new Size(SystemParameters.PrimaryScreenWidth, SystemParameters.PrimaryScreenHeight);

                    this.CurItem.Background = new SolidColorBrush(Colors.Transparent);                

                    this.CurItem.CustomDown(pt);

                }

            }

    自定义的类:

            InkPresenter ip;

            DynamicRenderer dr;

     

            StylusPointCollection stylusPoints = null;

            /// <summary>

            /// 

            /// </summary>

            public NormalPen(Canvas owner)

            {

                ip = new InkPresenter(); 

                this.Content = ip;            

                dr = new DynamicRenderer();

                ip.AttachVisuals(dr.RootVisual, dr.DrawingAttributes);            

                this.StylusPlugIns.Add(dr);

            }

     

     

            private bool isdown = false;

     

            public void CustomDown(Point pt)

            {

                isdown = true;

                if (stylusPoints != null) { return; }

                stylusPoints = new StylusPointCollection(); 

                stylusPoints.Add(new StylusPoint(pt.X, pt.Y));

            }

    2011年9月13日 2:51

答案

  • 只是 InkCanvas 不是通过InkPresenter来更新笔迹的,他会调用 MS.Internal.Ink.InkCollectionBehavior.StylusInputBegin 〉 base.InkCanvas.InternalDynamicRenderer.Reset 来 在装饰层进行 OnDraw方法。InkPresenter 在这里作为一个容器使用,本身不起关键作用。还有我观察InkCanvas 有个 EditingCoordinator ,他的UserIsEditing状态在改变 StylusPoints中起了关键作用:

    [SecurityCritical]
    void IStylusEditing.AddStylusPoints(StylusPointCollection stylusPoints, bool userInitiated)
    {
        if (!this._disableInput)
        {
            if (!base.EditingCoordinator.UserIsEditing)
            {
                base.EditingCoordinator.UserIsEditing = true;
                this.StylusInputBegin(stylusPoints, userInitiated);
            }
            else
            {
                this.StylusInputContinue(stylusPoints, userInitiated);
            }
        }
    }
    
    
    


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • 已标记为答案 Jie BaoModerator 2011年9月20日 6:14
    • 取消答案标记 张柱敏 2011年9月22日 10:33
    • 已标记为答案 张柱敏 2011年9月22日 10:33
    • 取消答案标记 张柱敏 2011年9月24日 9:22
    • 已标记为答案 张柱敏 2011年9月24日 9:25
    • 取消答案标记 张柱敏 2011年9月27日 6:15
    • 已标记为答案 张柱敏 2011年9月28日 0:54
    2011年9月15日 9:55
    版主

全部回复

  • 你没有实时更新 ip 的Strokes集合。用下面的代码:

      public class NormalPen : ContentControl
      {
        ......
    
        public void CustomDown(Point pt)
        {
          isdown = true;
          dr.Enabled = true;
          if (stylusPoints != null) { return; }
          stylusPoints = new StylusPointCollection();
          stylusPoints.Add(new StylusPoint(pt.X, pt.Y));
          UpdateStrokes();
        }
    
        public void CustomMove(Point pt)
        {
          if (isdown)
          {
            stylusPoints.Add(new StylusPoint(pt.X, pt.Y));
            UpdateStrokes();
          }
        }
    
        public void CustomUp(Point pt)
        {
          if (isdown && stylusPoints != null)
          {
            stylusPoints.Add(new StylusPoint(pt.X, pt.Y));
            UpdateStrokes();
          }
          isdown = false;
        }
    
        private void UpdateStrokes()
        {
          ip.Strokes.Clear();
          Stroke stroke = new Stroke(stylusPoints);
          ip.Strokes.Add(stroke);
        }
      }
    

    Sincerely,


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年9月13日 9:38
    版主
  • 非常感谢!实时更新 ip 的Strokes集合,显示的是静态笔画,并不是DynamicRenderer在呈现层的笔画。这样绘制的话,速度快的话,会看到鼠标指针和绘制的轨迹之间有一个很明显的延迟。在inkcanvas中绘制时,是看不到这个延迟的。DynamicRenderer必须和InkPresenter一起使用吗?能不能单独使用?
    2011年9月14日 3:13
  • 只是 InkCanvas 不是通过InkPresenter来更新笔迹的,他会调用 MS.Internal.Ink.InkCollectionBehavior.StylusInputBegin 〉 base.InkCanvas.InternalDynamicRenderer.Reset 来 在装饰层进行 OnDraw方法。InkPresenter 在这里作为一个容器使用,本身不起关键作用。还有我观察InkCanvas 有个 EditingCoordinator ,他的UserIsEditing状态在改变 StylusPoints中起了关键作用:

    [SecurityCritical]
    void IStylusEditing.AddStylusPoints(StylusPointCollection stylusPoints, bool userInitiated)
    {
        if (!this._disableInput)
        {
            if (!base.EditingCoordinator.UserIsEditing)
            {
                base.EditingCoordinator.UserIsEditing = true;
                this.StylusInputBegin(stylusPoints, userInitiated);
            }
            else
            {
                this.StylusInputContinue(stylusPoints, userInitiated);
            }
        }
    }
    
    
    


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • 已标记为答案 Jie BaoModerator 2011年9月20日 6:14
    • 取消答案标记 张柱敏 2011年9月22日 10:33
    • 已标记为答案 张柱敏 2011年9月22日 10:33
    • 取消答案标记 张柱敏 2011年9月24日 9:22
    • 已标记为答案 张柱敏 2011年9月24日 9:25
    • 取消答案标记 张柱敏 2011年9月27日 6:15
    • 已标记为答案 张柱敏 2011年9月28日 0:54
    2011年9月15日 9:55
    版主
  • 非常感谢!能说一下他的运行过程吗?我反编译看了一下,都是在初始化的时候调用的,并没有看到实时传入stylusPoints,动态进行轨迹的显示。

    我就想实现多笔书写,在书写的时候,不能有明显的延迟。要是重写DynamicRenderer的话,技术以及工作量都太大了,还有其他的思路吗?急盼指点!不胜感激!

    2011年9月22日 10:42
  • 现在可以把DynamicRenderer的rootisual放入visualcollection中,进行动态展示。但是如果多笔的话,每一笔的动态展示怎么和DynamicRenderer的rootisual进行关联呢?假设我的触摸板支持2个点,我预先加入2个DynamicRenderer。

    代码如下:

     

        public class CustomCanvas : Canvas
        {
            internal VisualCollection Collection;
            public CustomCanvas()
            {
                Collection = new VisualCollection(this);
    
                DynamicRenderer dr = new DynamicRenderer();
                Collection.Add(dr.RootVisual);  
                this.StylusPlugIns.Add(dr);
    
                DynamicRenderer dr1 = new DynamicRenderer();
                Collection.Add(dr1.RootVisual);
                this.StylusPlugIns.Add(dr1);
            }
    
            protected override Visual GetVisualChild(int index)
            {
                return Collection[index];
            }
    
            protected override int VisualChildrenCount
            {
                get
                {
                    int count = Collection.Count;
                    return count;
                }
            }
    
            protected override void OnStylusDown(StylusDownEventArgs e)
            {
                ??
            }
    }
    
    OnStylusDown里面应该如何进行处理呢?

     


     

     

    2011年9月25日 6:50
  • 版主在吗?急盼指点!如果使用Inkcanvas的话,能实现多笔自由画线吗?还有其他的实现思路吗?我现在被这个问题搞得头大死了。
    2011年9月27日 6:19
  • 看到了,不过不好意思,我也不是很熟悉。对于它的内部原理,我不确定所以不好说。

    还有,InkCanvas的多笔一般是由 触控 来操作。你要分开处理两个点的触控消息,分别让两个 DynamicRenderer 去绘制。

    我倒有个建议,你在WPF英文论坛发个贴子吧,那里我可以帮你把贴子提交到更高一层的技术支持哪,看看能不能得到WPF产品组相关的答复。中文这边我不好提交。


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年9月27日 19:43
    版主
  • 非常感谢!我去那边看一下。
    2011年9月28日 0:54
  • 我已上报了你的这个英文贴.应该会有些新的回复的.
    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年9月29日 9:01
    版主