2010-10-27 2 views
3

код ниже рисует две вертикальные линии на холсте. эти линии кажутся различной толщины на экране, хотя они одинаковы в коде. я привязываюсь, чтобы найти способ сделать их такими же резкими, как граница вокруг холста. установка Path.SnapsToDevicePixels не имеет никакого эффекта. Код - это надуманный пример, и вообще холст, который отображает эти строки, может быть вложен глубже в визуальное дерево.проблема с псевдонимом

спасибо за любую помощь константин


<Window x:Class="wpfapp.MyWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <Grid> 
    <Border BorderBrush="Black" 
      BorderThickness="1" 
      Margin="10"> 
     <Canvas x:Name="Canvas" 
       SizeChanged="OnCanvasSizeChanged" /> 
    </Border> 
    </Grid> 
</Window> 

using System.Windows; 
using System.Windows.Media; 
using System.Windows.Shapes; 

namespace wpfapp 
{ 
    public partial class MyWindow : Window 
    { 
     public MyWindow() 
     { 
      InitializeComponent(); 
     } 

     private void OnCanvasSizeChanged(object sender, SizeChangedEventArgs e) 
     { 
      StreamGeometry g = new StreamGeometry(); 
      double h = this.Canvas.ActualHeight; 

      using (StreamGeometryContext c = g.Open()) 
      { 
       c.BeginFigure(new Point(7, 0), false, false); 
       c.LineTo(new Point(7, h), true, false); 

       c.BeginFigure(new Point(14, 0), false, false); 
       c.LineTo(new Point(14, h), true, false); 
      } 
      g.Freeze(); 

      Path p = new Path(); 

      p.Data = g; 
      p.SnapsToDevicePixels = true; 
      p.Stroke = new SolidColorBrush(Colors.Black); 
      p.StrokeThickness = 1; 

      this.Canvas.Children.Clear(); 
      this.Canvas.Children.Add(p); 
     } 
    } 
} 
+0

только догадка, но попробуйте установить SnapsToDevicePixels на каждом элементе в дереве, содержащем Canvas. Привязка отдельного элемента к пикселям устройства не помогает, если векторы преобразуются в не выровненные координаты дальше по конвейеру рендеринга. –

ответ

2

нужно использовать GuidelineSet:


     protected override void OnRender(DrawingContext c) 
     { 
      base.OnRender(c); 

      Pen pen = new Pen(Brushes.Black, 1); 
      double h = this.ActualHeight; 
      double d = pen.Thickness/2; 

      foreach (double x in new double[] { 7, 14 }) 
      { 
       GuidelineSet g = new GuidelineSet(new double[] { x + d }, 
                new double[] { 0 + d, h + d }); 

       c.PushGuidelineSet(g); 
       c.DrawLine(pen, new Point(x, 0), new Point(x, h)); 
       c.Pop(); 
      } 
     } 
Смежные вопросы