2010-11-22 5 views
0

mon code ci-dessous est censé afficher N lignes par pouce. Au lieu de cela, je reçois un peu plus de N lignes par pouce. la distance entre les lignes est un peu plus petite. De plus, en changeant la résolution de l'écran, la distance entre les lignes change également. Est-ce que quelqu'un sait comment gérer cela?comment dessiner N lignes par pouce?


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

Je suppose que c'est juste un exemple de code, mais il semble que vous allez toujours dessiner 10 lignes. Pas N lignes par pouce. Je pourrais manquer quelque chose, mais je suis sûr que la boucle for de 0 à 9 va tirer 10 lignes. Aussi, vous devriez mettre le Pen dans une instruction using (en utilisant var p = new Pen ...) sinon vous finirez par perdre des handles GDI. – pstrjds

+0

oui, c'est un exemple de code. oui il dessine dix lignes. il est supposé dessiner ces dix lignes de façon à ce qu'elles soient à 1/N pouce l'une de l'autre. – akonsu

+0

D'accord, je voudrais peut-être modifier la question pour expliquer que, je l'ai lu que vous voulez N lignes par pouce et non 10 lignes avec une distance de 1/N entre eux. En fait, en relisant votre question, je suis un peu confus, vous dites que l'écart change à mesure que la résolution change, mais c'est exactement ce que vous voulez faire si vous voulez seulement 10 lignes avec une distance entre la résolution actuelle la distance change à mesure que la résolution change. – pstrjds

Répondre

1

cet article semble discuter du même problème: WPF DPI issues il n'y a pas de solution à ce problème autre que de demander à l'utilisateur de définir les paramètres DPI correct qui correspondent au DPI physique de l'écran. Je trouve que cela rend la vie un peu plus facile est d'utiliser la mise à l'échelle de l'application WPF comme décrit ici: http://www.odewit.net/ArticleContent.aspx?id=WpfDpiScaling&lang=en&format=html

+0

Je pensais que le problème avait trait aux différences de résolution et à l'arrondissement. Je fais beaucoup de travail avec le développement d'interfaces pour que les utilisateurs puissent expri- mer des informations à partir d'images. La mise à l'échelle et la résolution sont parmi les choses les plus difficiles à gérer (ce qui arrive à une boîte lorsqu'un utilisateur zoome et sort, ce qui se passe quand il change sa résolution, etc.). On dirait que la classe de perspective (liée dans l'article que vous avez lié: http://perspective.codeplex.com/ accomplira ce dont vous avez besoin. – pstrjds

0

Vous ne savez pas si cela répondrait à vos attentes, mais cela devrait être utile en cas d'arrondi. Comme je l'ai dit dans les commentaires, votre code semble plutôt correct, je pense que c'est un problème d'arrondi avec le calcul de dpi. Étant donné que vous souhaitez effectuer un rendu basé sur 96 ppp, calculez les coordonnées basées sur 96 ppp, puis convertissez les points sur votre appareil. Je l'ai écrit plus pour plus de clarté, vous pouvez utiliser un seul tableau de points et rappelez-vous juste que i est le point de départ et i+1 est le point final et alors vous auriez à faire un seul appel pour transformer les points.

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]); 
       } 
      } 
     } 
    } 
+0

merci pour votre aide. il semble que tu n'as pas échappé à un signe moins qu'à la deuxième ligne ... – akonsu

+0

bonne prise, j'avais l'intention de couper/coller la ligne quand je l'éditais et apparemment copier/coller à la place. Devrait être réparé maintenant. – pstrjds