2012-10-20 110 views
2

這裏有一個Windows窗體程序,繪製正方形的二維網格是隨機黑色或紅色:高效繪製二維網格在WPF

using System; 
using System.Drawing; 
using System.Windows.Forms; 

namespace Forms_Panel_Random_Squares 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 

      Width = 350; 
      Height = 350; 

      var panel = new Panel() { Dock = DockStyle.Fill }; 

      Controls.Add(panel); 

      var random = new Random(); 

      panel.Paint += (sender, e) => 
       { 
        e.Graphics.Clear(Color.Black); 

        for (int i = 0; i < 30; i++) 
         for (int j = 0; j < 30; j++) 
         { 
          if (random.Next(2) == 1) 
           e.Graphics.FillRectangle(
            new SolidBrush(Color.Red), 
            i * 10, 
            j * 10, 
            10, 
            10); 
         } 
       }; 
     } 
    } 
} 

產生的程序看起來是這樣的:

enter image description here

下面是使用Rectangle對象爲每平方(幼稚)翻譯WPF:

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

namespace WPF_Canvas_Random_Squares 
{ 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 

      Width = 350; 
      Height = 350; 

      var canvas = new Canvas(); 

      Content = canvas; 

      Random random = new Random(); 

      Rectangle[,] rectangles = new Rectangle[30, 30]; 

      for (int i = 0; i < rectangles.GetLength(0); i++) 
       for (int j = 0; j < rectangles.GetLength(1); j++) 
       { 
        rectangles[i, j] = 
         new Rectangle() 
         { 
          Width = 10, 
          Height = 10, 
          Fill = random.Next(2) == 0 ? Brushes.Black : Brushes.Red, 
          RenderTransform = new TranslateTransform(i * 10, j * 10) 
         }; 

        canvas.Children.Add(rectangles[i, j]); 
       } 
     } 
    } 
} 

由於世界上的每個單元都有一個對象的開銷,WPF版本似乎是更多內存低效的方式。

有沒有一種方法可以以與Forms版本一樣高效的風格編寫該程序?或者是沒有辦法創建所有這些Rectangle對象?

+1

你想要的對象,或者只是改變背景顏色和你需要使用一個Canvas不是網格 –

+0

的,我想呈現的狀態在一個二維數組。所以我不需要在視圖層面上沉重的對象表示。 – dharmatech

+1

看看'DrawingContext'這個[SO回答](http://stackoverflow.com/a/2944417/479512)建議 –

回答

2

這裏是一個純粹的WPF解決方案。 FrameworkElement被分類。這個新的子類(DrawingVisualElement)公開了一個可用於繪製的對象DrawingVisual

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

namespace DrawingVisualSample 
{ 
    public class DrawingVisualElement : FrameworkElement 
    { 
     private VisualCollection _children; 

     public DrawingVisual drawingVisual; 

     public DrawingVisualElement() 
     { 
      _children = new VisualCollection(this); 

      drawingVisual = new DrawingVisual(); 
      _children.Add(drawingVisual); 
     } 

     protected override int VisualChildrenCount 
     { 
      get { return _children.Count; } 
     } 

     protected override Visual GetVisualChild(int index) 
     { 
      if (index < 0 || index >= _children.Count) 
       throw new ArgumentOutOfRangeException(); 

      return _children[index]; 
     } 
    } 

    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 

      Width = 350; 
      Height = 350; 

      var stackPanel = new StackPanel(); 

      Content = stackPanel; 

      var drawingVisualElement = new DrawingVisualElement(); 

      stackPanel.Children.Add(drawingVisualElement); 

      var drawingContext = drawingVisualElement.drawingVisual.RenderOpen(); 

      var random = new Random(); 

      for (int i = 0; i < 30; i++) 
       for (int j = 0; j < 30; j++)  
        drawingContext.DrawRectangle(
         random.Next(2) == 0 ? Brushes.Black : Brushes.Red, 
         (Pen)null, 
         new Rect(i * 10, j * 10, 10, 10)); 

      drawingContext.Close(); 
     } 
    }  
} 
0

可以混合使用WPF和Forms。因此,可以通過WindowsFormsHost將面板嵌入到WPF窗口中,而不必使用純粹的Forms路徑。這是一個WPF程序,它演示了這一點:

using System; 
using System.Windows; 
using System.Windows.Forms.Integration; 
using System.Drawing; 

namespace WindowsFormsHost_Random_Squares 
{ 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 

      Width = 350; 
      Height = 350; 

      Random random = new Random(); 

      var windowsFormsHost = new WindowsFormsHost(); 

      Content = windowsFormsHost; 

      var panel = new System.Windows.Forms.Panel() 
      { Dock = System.Windows.Forms.DockStyle.Fill }; 

      windowsFormsHost.Child = panel; 

      panel.Paint += (sender, e) => 
       { 
        e.Graphics.Clear(System.Drawing.Color.Black); 

        for (int i = 0; i < 30; i++) 
         for (int j = 0; j < 30; j++) 
         { 
          if (random.Next(2) == 1) 
           e.Graphics.FillRectangle(
            new SolidBrush(System.Drawing.Color.Red), 
            i * 10, 
            j * 10, 
            10, 
            10); 
         } 
       }; 
     } 
    } 
}