2010-11-22 89 views
0

我下面的代码应该显示每英寸N行。相反,我得到了每英寸多N行。线之间的距离稍小。另外,改变屏幕分辨率也会改变线条之间的距离。有谁知道如何处理?如何绘制每英寸N行?


using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Media; 

namespace MyApp 
{ 
    class MyControl : Control 
    { 
     private readonly ContainerVisual container = new ContainerVisual(); 
     private readonly DrawingVisual drawing = new DrawingVisual(); 

     private void RenderDrawing() 
     { 
      var s = PresentationSource.FromVisual(this); 
      var dpiX = 96 * s.CompositionTarget.TransformToDevice.M11; 
      var dpiY = 96 * s.CompositionTarget.TransformToDevice.M22; 

      double N = 1; 

      using (var c = drawing.RenderOpen()) 
      { 
       var p = new Pen(new SolidColorBrush(Colors.Black), 1); 

       for (int i = 0; i < 10; i++) 
       { 
        var x = i * dpiX/N; 
        c.DrawLine(p, new Point(x, 0), new Point(x, 100)); 
       } 
      } 
     } 

     protected override Size ArrangeOverride(Size s) 
     { 
      RenderDrawing(); 
      return s; 
     } 

     protected override Visual GetVisualChild(int index) 
     { 
      return container; 
     } 

     protected override Size MeasureOverride(Size s) 
     { 
      return new Size(); 
     } 

     protected override int VisualChildrenCount 
     { 
      get { return 1; } 
     } 

     public MyControl() 
     { 
      container.Children.Add(drawing); 
      AddVisualChild(container); 
     } 
    } 
} 
+0

我假设这只是一些示例代码,但它似乎总是要绘制10行。不是每英寸有N行。我可能会错过一些东西,但我很确定从0到9的for循环将绘制10行。此外,你应该把笔放在使用语句中(使用var p = new Pen ...),否则你最终会泄漏GDI句柄。 – pstrjds 2010-11-22 19:44:18

+0

是的,它是示例代码。是的,它画了十条线。它应该绘制这十条线,使它们相隔1/N英寸。 – akonsu 2010-11-22 19:46:19

+0

好吧,我可能会编辑这个问题来解释一下,我读它是因为你需要每英寸N行而不是10行,它们之间的距离为1/N。事实上,再次读你的问题我有点困惑,你说差距会随着分辨率的变化而改变,但如果你只需要10行,并且基于当前分辨率的距离,那就是你想要发生的事情,然后距离随分辨率变化而变化。 – pstrjds 2010-11-22 19:48:43

回答

0

不知道这是否会完成您正在寻找的内容,但如果问题与四舍五入有关,它应该有所帮助。正如我在评论中所说的,您的代码看起来基本正确,我认为这是dpi计算的一个圆滑问题。由于您希望基于96 dpi进行渲染,因此请根据96dpi计算坐标,然后将这些点转换为您的设备。为了清晰起见,我更多地写了这些内容,可以使用单个点阵列,只记得i是开始点,i+1是终点,然后您只需进行一次调用即可转换点。

private void RenderDrawing() 
    { 
     var s = PresentationSource.FromVisual(this); 
     var dpiX = 96; 

     int numberOfLines = 10; 
     double N = 1; 
     double spacing = dpiX/N; 

     var startPoints = new Point[numberOfLines](); 
     var endPoints = new Point[numberOfLines](); 
     for (int i = 0; i < numberOfLines; i++) 
     { 
      var x = i * spacing; 
      startPoints[i] = new Point(x, 0); 
      endPoints[i] = new Point(x, 100);     
     } 
     s.CompositionTarget.TransformToDevice.Transform(startPoints); 
     s.CompositionTarget.TransformToDevice.Transform(endPoints); 

     using (var c = drawing.RenderOpen()) 
     { 
      using (var p = new Pen(new SolidColorBrush(Colors.Black), 1)) 
      { 
       for(int i=0; i < numberOfLines; i++) 
       { 
        c.DrawLine(p, startPoints[i], endPoints[i]); 
       } 
      } 
     } 
    }