2

这是一个 Windows 窗体程序,它绘制了一个由随机着色为黑色或红色的正方形的二维网格:

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);
                        }
                };
        }
    }
}

生成的程序如下所示:

在此处输入图像描述

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 版本似乎内存效率更低Rectangle

有没有办法以与 Forms 版本一样高效的风格编写这个程序?还是没有办法创建所有这些Rectangle对象?

4

2 回答 2

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();
        }
    }    
}
于 2012-10-21T22:10:54.223 回答
0

可以混合使用 WPF 和表单。因此,Panel 可以通过WindowsFormsHost. 这是一个演示这一点的 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);
                        }
                };
        }
    }
}
于 2012-10-21T00:23:23.973 回答