WPF 使用DrawingVisual和DispatchFrame快速提升绘图速度

  • A+
所属分类:.NET技术
摘要

参考资料:https://www.jianshu.com/p/d308641498aahttps://zhuanlan.zhihu.com/p/37167062 这是一个来自很久以前的代码

参考资料:

https://www.jianshu.com/p/d308641498aa

https://zhuanlan.zhihu.com/p/37167062

 

这是一个来自很久以前的代码

通过DrawingVisual和DispatchFrame快速提升绘图速度

代码里有两种,一种是组合线形成矩形,另外一种是直接生成矩形,两者不同就是是否可以精确控制某个矩形。

第一种形成的矩形会比第二多很多,也不会卡。如果某些绘图,单一颜色,效果会很好。

也可以通过变换矩形块在设置颜色也会有很多造型,或者重新编写图形。

WPF 使用DrawingVisual和DispatchFrame快速提升绘图速度

 

截图2

WPF 使用DrawingVisual和DispatchFrame快速提升绘图速度

 

最主要的是继承DrawingVisual和修改canvas。

  public class BaseCanvas : Canvas     {         public ObservableCollection<BaseDrawVisual> Visuals         {             get;             private set;         }         ScaleTransform Scale;         public BaseCanvas()         {             Visuals = new ObservableCollection<BaseDrawVisual>();             Scale = new ScaleTransform();             this.RenderTransform = Scale;         }         double sc = 1;         protected override void OnMouseWheel(MouseWheelEventArgs e)         {            // base.OnMouseWheel(e);            if(e.Delta>0)             {                 sc += 0.5;             }             else             {                 sc -= 0.5;             }             if (sc > 48)                 sc = 48;             if (sc < 0.5)                 sc = 0.5;             Scale.CenterX = 0;             Scale.CenterY = 0;             Scale.ScaleX = sc;             Scale.ScaleY = sc;             Console.WriteLine("sc:"+sc);            // base.OnMouseWheel(e);         }         protected override Visual GetVisualChild(int index)         {             return Visuals[index];         }         protected override int VisualChildrenCount => Visuals.Count;          public void AddVisual(BaseDrawVisual drawVisual)         {             Visuals.Add(drawVisual);             AddVisualChild(drawVisual);             AddLogicalChild(drawVisual);         }         public void DelAllVisual()         {             foreach (var item in Visuals)             {                 RemoveVisualChild(item);                 RemoveLogicalChild(item);             }             Visuals.Clear();         }       }

 

部分元素

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Media;  namespace DrawCanvas {     public class RectByLineDrawVisual : BaseDrawVisual //也可以直接继承DrawingVisual     {         public RectByLineDrawVisual()         {          }           public RectByLineDrawVisual(double X, double Y, double width, double height, double rectW, double rectH)         {             this.LocationX = X;             this.LocationY = Y;             this.DrawWidth = width;             this.DrawHeight = height;             this.RectWidth = rectW;             this.RectHeight = rectH;              MaxItems = (int)(DrawHeight / RectHeight * DrawWidth / RectWidth);             SelectItem = new List<int[]>();         }           public double DrawHeight { get; set; }         public double DrawWidth { get; set; }         public double RectHeight { get; set; }         public double RectWidth { get; set; }         public double LocationX { get; set; }         public double LocationY { get; set; }          public Pen DrawPen = DrawSetting.Instance.DrawPen;          public override void Draw()         {             DrawPen.Freeze();             using (var BaseDrawing = this.RenderOpen())             {                 GeometryGroup gp = new GeometryGroup();                 gp.Children.Add(new RectangleGeometry(new Rect(LocationX, LocationY, DrawWidth, DrawHeight)));                  for (double x = LocationX; x < LocationX + DrawWidth; x += RectWidth)                 {                     gp.Children.Add(                       new LineGeometry(new Point(x, LocationY), new Point(x, LocationY+DrawHeight)));                                     }                 for (double y = LocationY; y < LocationY + DrawHeight; y += RectHeight)                 {                     gp.Children.Add(                    new LineGeometry(new Point(LocationX, y), new Point(LocationX+DrawWidth, y)));                 }                 BaseDrawing.DrawDrawing(new GeometryDrawing(DrawColor, DrawPen, gp));             }         }     } }

 

主界面cs

public partial class MainWindow : Window     {         public MainWindow()         {             InitializeComponent();           }          private void Window_Loaded(object sender, RoutedEventArgs e)         {             //   Draw();              e.Handled = true;         }         Random GetRandom = new Random();         int k = 0;         private void Draw()         {             draw.DelAllVisual();             for (double i = 0; i < draw.ActualWidth; i +=100)             {                 for (double j = 0; j < draw.ActualHeight; j += 100)                 {                     //NormColor=new SolidColorBrush(Color.FromRgb((byte)GetRandom.Next(1,255), (byte)GetRandom.Next(1, 255), (byte)GetRandom.Next(1, 255)))                      //draw.AddVisual(new RectByLineDrawVisual(i, j, 80, draw.ActualHeight, 5, 5));                     draw.AddVisual(new RectDrawVisual(i, j, 100, 100, 4, 4));                 }             }         }          private void Window_SizeChanged(object sender, SizeChangedEventArgs e)         {             // Draw();          }         private void ProcessMsgs()         {              DoEvents();         }         public void DoEvents()         {             DispatcherFrame frame = new DispatcherFrame();             Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background,                 new DispatcherOperationCallback(ExitFrames), frame);             Dispatcher.PushFrame(frame);         }          public object ExitFrames(object f)         {             ((DispatcherFrame)f).Continue = false;              return null;         }          private void Button_Click(object sender, RoutedEventArgs e)         {             Draw();             for (int i = 0; i < draw.Visuals.Count; i++)             {                  draw.Visuals[i].Draw();                 if (i % 10 == 0)                     ProcessMsgs();             }             //   this.IsEnabled = true;         }         DispatcherTimer Timer = new DispatcherTimer();         private void Button_Click_1(object sender, RoutedEventArgs e)         {             if (Timer.IsEnabled)             {                 Timer.Stop();                 return;             }             Timer.Interval = TimeSpan.FromMilliseconds(50);             Timer.Tick += Timer_Tick;             Timer.Start();          }          private void Timer_Tick(object sender, EventArgs e)         {           Changed1();             //Changed2();         }         void Changed1()         {             for (int i = 0; i < draw.Visuals.Count;)             {                 var index = GetRandom.Next(0, draw.Visuals.Count);                  var item = draw.Visuals[index] as RectDrawVisual;                 //  item.SelectItem.Clear();                 var k = new[] { GetRandom.Next(0, 20), GetRandom.Next(0, 20) };                 if (!item.SelectItem.Contains(k))                     item.SelectItem.Add(k);                 else                     item.SelectItem.Remove(k);                 item.SelectItemBackGround = new SolidColorBrush(Colors.Red);//new SolidColorBrush(Color.FromRgb((byte)GetRandom.Next(1, 255), (byte)GetRandom.Next(1, 255), (byte)GetRandom.Next(1, 255)));                 item.Draw();                 ProcessMsgs();                 Console.WriteLine(index);                 if (i == draw.Visuals.Count - 1)                 {                     i = 0;                     ProcessMsgs();                     continue;                  }                 else                     i++;             }         }         void Changed2()         {             var index = GetRandom.Next(0, draw.Visuals.Count - 1);             var item = draw.Visuals[index];             item.DrawColor = new SolidColorBrush(Color.FromRgb((byte)GetRandom.Next(1, 255), (byte)GetRandom.Next(1, 255), (byte)GetRandom.Next(1, 255)));             item.Draw();            // ProcessMsgs();         }     }

 

 

下载代码