The following code draws rectangles in 2D grid. Everything is working fine except it is really slow when it has to draw more than 50,000 squares. I know it sounds like a lot of squares but I have the same program written in C++/Qt
and it's a lot faster, it draws the 50,000 almost instantaneously wheres in C#/WPF it takes 50 seconds.
Is there a better/faster way to draw rectangles on the screen in WPF?
XAML
<Window x:Class="DrawingRectanglesWithMvvmLight.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ignore="http://www.galasoft.ch/ignore"
mc:Ignorable="d ignore"
Height="319"
Width="453.333"
Title="MVVM Light Application"
DataContext="{Binding Main, Source={StaticResource Locator}}">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Skins/MainSkin.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid x:Name="LayoutRoot" Margin="0,0,2,0" Height="194" VerticalAlignment="Top" Background="#FF3E7AAC">
<ItemsControl ItemsSource="{Binding PartsGrid}" Height="200" Margin="5,0,10,-6">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Background="#FFF1F0F0" Margin="10" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Rectangle
Width="{Binding Width}"
Height="{Binding Height}"
Margin="{Binding Margin}"
Fill="{Binding Fill}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Grid Margin="5,236,6,-69">
<Button Content="Draw" Command="{Binding DrawCommand}" Margin="328,0,10,0" />
<Button Content="Reset" Command="{Binding ResetCommand}" Margin="263,0,109,0" />
<TextBox Text="{Binding Width}" RenderTransformOrigin="1.049,2.023" Margin="124,0,200,0"/>
<TextBox Text="{Binding Height}" Margin="0,0,334,0"/>
</Grid>
</Grid>
</Window>
Class:
namespace MvvmLightTEST.Model
{
public class FSRectangle
{
public double Width { get; set; }
public double Height { get; set; }
public Thickness Margin { get; set; }
public Brush Fill { get; set; }
}
}
ViewModel:
namespace DrawingRectanglesWithMvvmLight.ViewModel
{
public class MainViewModel : ViewModelBase
{
public ObservableCollection<FSRectangle> PartsGrid { get; } = new ObservableCollection<FSRectangle>();
public RelayCommand DrawCommand { get; }
public RelayCommand ResetCommand { get; }
public double Width { get; set; }
public double Height { get; set; }
public MainViewModel(IDataService dataService)
{
DrawCommand = new RelayCommand(Draw);
ResetCommand = new RelayCommand(Clear);
}
private void Draw()
{
Clear();
int xParts = 250;
int yParts = 200;
for (int i = 0; i < xParts; i++) {
for (int j = 0; j < yParts; j++) {
FSRectangle part = new FSRectangle();
part.Width = Width;
part.Height = Height;
part.Margin = new Thickness((part.Width + 1) * i, (part.Height + 1) * j, 0, 0);
part.Fill = new SolidColorBrush(Color.FromArgb(170, 51, 51, 255));
PartsGrid.Add(part);
}
}
}
private void Clear()
{
PartsGrid.Clear();
}
}
}
UI
By not using MVVM due to the slow performance for this use case. Rectangles are FrameworkElement
s which contain layout, a feature that does not scale This is discussed many times in SO.
You might want to consider
DrawingVisual
and ContainerVisual
for lower level rendering with no layout overhead Image courtesy Microsoft, used without permission.
MSDN has this to say on DrawingVisual
The DrawingVisual is a lightweight drawing class that is used to render shapes, images, or text. This class is considered lightweight because it does not provide layout or event handling, which improves its runtime performance . For this reason, drawings are ideal for backgrounds and clip art. The DrawingVisual can be used to create a custom visual object.
使用RectangleGeometry的路径是一个选项: https : //docs.microsoft.com/zh-cn/dotnet/framework/wpf/graphics-multimedia/how-to-define-a-rectangle-using-a-rectanglegeometry
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.