I'm trying to make an app(for college) which shows two rectangles which represent a clock. I have two rectangles, one which respresents seconds and the other minutes. The width must be adjusted every second to correspond to the time.
public partial class MainWindow : Window
{
Rectangle rectMinuut = new Rectangle();
Rectangle rectSeconde = new Rectangle();
public MainWindow()
{
InitializeComponent();
rectMinuut.Stroke = new SolidColorBrush(Colors.Black);
rectSeconde.Stroke = new SolidColorBrush(Colors.DarkBlue);
rectSeconde.Fill = new SolidColorBrush(Colors.DarkBlue);
rectMinuut.Fill = new SolidColorBrush(Colors.Black);
rectSeconde.Height = 100;
rectMinuut.Height = 100;
var date = DateTime.Now;
int widthMinute = date.Minute;
int widthSecond = date.Second;
rectMinuut.Width = widthMinute;
rectSeconde.Width = widthSecond;
Canvas.SetTop(rectMinuut, 50);
Canvas.SetTop(rectSeconde, 150);
paperCanvas.Children.Add(rectSeconde);
paperCanvas.Children.Add(rectMinuut);
Timer timer = new Timer();
timer.Interval = (1000);
timer.Elapsed += new ElapsedEventHandler(timer_Tick);
timer.Start();
}
private void timer_Tick(object sender, ElapsedEventArgs e)
{
//refresh here...
var date = DateTime.Now;
int widthMinute = date.Minute;
int widthSecond = date.Second;
rectMinuut.Width = widthMinute;
rectSeconde.Width = widthSecond;
}
}}
I tried different options, but my application always crashes when assigning a new value to rectMinuut.Width in the timer_Tick method.
Edit: Correct answer:
using System.Windows.Threading;
public partial class MainWindow : Window
{
private DispatcherTimer timer = new DispatcherTimer();
public MainWindow()
{
InitializeComponent();
timer.Interval = TimeSpan.FromMilliseconds(200); //200ms, because code takes time to execute too
timer.Tick += timer_Tick;
timer.Start();
}
private void timer_Tick(object sender, EventArgs e)
{
//refresh here...
Rectangle rectMinuut = new Rectangle();
Rectangle rectSeconde = new Rectangle();
rectMinuut.Stroke = new SolidColorBrush(Colors.Black);
rectSeconde.Stroke = new SolidColorBrush(Colors.DarkBlue);
rectSeconde.Fill = new SolidColorBrush(Colors.DarkBlue);
rectMinuut.Fill = new SolidColorBrush(Colors.Black);
rectSeconde.Height = 100;
rectMinuut.Height = 100;
var date = DateTime.Now;
int widthMinute = date.Minute * 2; //increase/scale width
int widthSecond = date.Second * 2;
rectMinuut.Width = widthMinute;
rectSeconde.Width = widthSecond;
Canvas.SetTop(rectMinuut, 50);
Canvas.SetTop(rectSeconde, 150);
paperCanvas.Children.Add(rectSeconde);
paperCanvas.Children.Add(rectMinuut);
}
}
}
Related
I have the following code:
using Microsoft.Expression.Shapes;
Arc a = new Arc();
a.ArcThicknessUnit = Microsoft.Expression.Media.UnitType.Pixel;
a.ArcThickness = 10;
a.StrokeThickness = 1;
a.Fill = new SolidColorBrush(Colors.Aqua);
a.Stroke = new SolidColorBrush(Colors.DarkMagenta);
a.StartAngle = 0;
a.EndAngle = 360;
a.Width = 200;
a.Height = 200;
a.Stretch = Stretch.None;
_myStackPanel.Children.Add(a);
DispatcherTimer dt = new DispatcherTimer();
dt.Interval = TimeSpan.FromMilliseconds(1);
dt.Tick += (s, e) => { a.StartAngle = a.StartAngle + 4; };
dt.Start();
When it is executed I get an "erasable circle". I need to get the opposite effect. Сircle drawing effect. How can I change the code to get a "drawn circle"? Circle Drawning Example
Change the EndAngle instead of the StartAngle:
using Microsoft.Expression.Shapes;
Arc a = new Arc();
a.ArcThicknessUnit = Microsoft.Expression.Media.UnitType.Pixel;
a.ArcThickness = 10;
a.StrokeThickness = 1;
a.Fill = new SolidColorBrush(Colors.Aqua);
a.Stroke = new SolidColorBrush(Colors.DarkMagenta);
a.StartAngle = 0;
a.EndAngle = 0;//Start as 0
a.Width = 200;
a.Height = 200;
a.Stretch = Stretch.None;
_myStackPanel.Children.Add(a);
DispatcherTimer dt = new DispatcherTimer();
dt.Interval = TimeSpan.FromMilliseconds(1);
dt.Tick += (s, e) => { a.EndAngle = a.EndAngle + 4; };//update EndAngle
dt.Start();
I have a problem creating a class that generates labels with specific weight and height, it works on the code, but doesn't show up on the form when I create the object. how I can solve this problem guys?
class cub
{
public int cubWeight = 150;
public int cubHeight = 150;
public void createNewCub()
{
Label cubLabel = new Label();
cubLabel.Size = new Size(cubWeight, cubHeight);
cubLabel.Text = "GeeksforGeeks";
cubLabel.Location = new Point(500, 200);
cubLabel.Font = new Font("Calibri", 18);
cubLabel.ForeColor = Color.Green;
cubLabel.Padding = new Padding(6);
}
}
public Form1()
{
InitializeComponent();
label1.Text = "Number of cubs: " + trackBar1.Value;
label2.Text = "Number of seconds: " + trackBar2.Value;
cub xxx = new cub();
xxx.createNewCub();
)
how I can solve this problem?
You can do like this: Edit from your code
public Form1()
{
InitializeComponent();
cub xxx = new cub();
this.Controls.Add(xxx.createNewCub()); // Add the Label
}
class cub
{
public int cubWeight = 150;
public int cubHeight = 150;
public Label createNewCub() //change void to Label
{
Label cubLabel = new Label();
cubLabel.Size = new Size(cubWeight, cubHeight);
cubLabel.Text = "GeeksforGeeks";
cubLabel.Location = new Point(500, 200);
cubLabel.Font = new Font("Calibri", 18);
cubLabel.ForeColor = Color.Green;
cubLabel.Padding = new Padding(6);
return cubLabel; //return label
}
}
I want show multi marker on Map , but seem can't , code follow :
button1_Click show Position ,button2_Click show markers !
anyone give me any instructions? thanks.
private void button1_Click(object sender, EventArgs e)
{
gmap.DragButton = MouseButtons.Left;
gmap.MapProvider = GMapProviders.GoogleMap;
gmap.Position = new PointLatLng(25.037531, 121.5639969);
gmap.MinZoom = 5;
gmap.MaxZoom = 100;
gmap.ShowCenter = false;
gmap.Zoom = 15;
}
private void button2_Click(object sender, EventArgs e)
{
Random r = new Random();
var marker = new GMarkerGoogle(new PointLatLng(r.Next(25, 500), 121), GMarkerGoogleType.green);
var marker1 = new GMarkerGoogle(new PointLatLng(r.Next(25, 500), 121), GMarkerGoogleType.pink);
var marker2 = new GMarkerGoogle(new PointLatLng(r.Next(25, 500), 121), GMarkerGoogleType.blue);
var marker3 = new GMarkerGoogle(new PointLatLng(r.Next(25, 500), 121), GMarkerGoogleType.yellow);
marker.IsVisible = true; marker1.IsVisible = true; marker2.IsVisible = true; marker3.IsVisible = true;
gMapOverlay.Markers.Add(marker);
gMapOverlay.Markers.Add(marker1);
gMapOverlay.Markers.Add(marker2);
gMapOverlay.Markers.Add(marker3);
gmap.Overlays.Add(gMapOverlay);
}
Your code is ok, but the problem with the random function that you use only generates integers, and a small change as 1 integer means changing a complete degree in either latitude or longitude and this is a hudge displacement.
So you have to generate a random Doubles number instead of Integers.
I edit the code to work correctly.
using GMap.NET;
using GMap.NET.WindowsForms.Markers;
public class Form1
{
private GMap.NET.WindowsForms.GMapOverlay gMapOverlay;
private Random rand = new Random();
private void Form1_Load(object sender, EventArgs e)
{
GMapControl1.DragButton = MouseButtons.Left;
GMapControl1.MapProvider = GMap.NET.MapProviders.GMapProviders.GoogleMap;
GMapControl1.Position = new PointLatLng(25.037531, 121.5639969);
GMapControl1.MinZoom = 5;
GMapControl1.MaxZoom = 20;
GMapControl1.ShowCenter = false;
GMapControl1.Zoom = 11;
gMapOverlay = new WindowsForms.GMapOverlay("markers");
gMapOverlay.IsVisibile = true;
}
private void button2_Click(object sender, EventArgs e)
{
var marker = new GMarkerGoogle(new PointLatLng(GetRandomDouble(24.8, 25.1), GetRandomDouble(121.3, 121.6)), GMarkerGoogleType.green);
var marker1 = new GMarkerGoogle(new PointLatLng(GetRandomDouble(24.8, 25.1), GetRandomDouble(121.3, 121.6)), GMarkerGoogleType.pink);
var marker2 = new GMarkerGoogle(new PointLatLng(GetRandomDouble(24.8, 25.1), GetRandomDouble(121.3, 121.6)), GMarkerGoogleType.blue);
var marker3 = new GMarkerGoogle(new PointLatLng(GetRandomDouble(24.8, 25.1), GetRandomDouble(121.3, 121.6)), GMarkerGoogleType.yellow);
marker.IsVisible = true;
marker1.IsVisible = true;
marker2.IsVisible = true;
marker3.IsVisible = true;
// Clear old markers
gMapOverlay.Markers.Clear();
gMapOverlay.Markers.Add(marker);
gMapOverlay.Markers.Add(marker1);
gMapOverlay.Markers.Add(marker2);
gMapOverlay.Markers.Add(marker3);
// Clear old overlay
GMapControl1.Overlays.Clear();
GMapControl1.Overlays.Add(gMapOverlay);
// Zoom the map to show all drawn markers
GMapControl1.ZoomAndCenterMarkers(gMapOverlay.Id);
}
public double GetRandomDouble(double min, double max)
{
return rand.NextDouble() * (max - min) + min;
}
I use a .NET Winform version teechart 4.1.2012.1032.
I modified the sample that you supplied. "Extended\Reducing number of points\DownSampling Additions"
But When I zoom in chart, fastline's marks count is not 100 , downSampling.DisplayedPointCount.
How can I resolve it?
private void InitializeChart()
{
this.cursorTool1 = new Steema.TeeChart.Tools.CursorTool();//
this.tChart1.Tools.Add(this.cursorTool1);//
this.cursorTool1.FollowMouse = true;//
this.cursorTool1.Style = Steema.TeeChart.Tools.CursorToolStyles.Vertical;//
this.cursorTool1.Change += new Steema.TeeChart.Tools.CursorChangeEventHandler(this.cursorTool1_Change);//
CreateArrays();
tChart1.Aspect.View3D = false;
tChart1.Zoom.Direction = ZoomDirections.Both;//.Horizontal;//
tChart1.Series.Add(points = new Steema.TeeChart.Styles.Points());
tChart1.Series.Add(fastLine = new Steema.TeeChart.Styles.FastLine());
downSampling = new Steema.TeeChart.Functions.DownSampling(tChart1.Chart);
points.Add(xValues, yValues);
points.Active = false;
downSampling.DisplayedPointCount = 100;
downSampling.Method = Steema.TeeChart.Functions.DownSamplingMethod.MinMaxFirstLast;// Null;
fastLine.TreatNulls = Steema.TeeChart.Styles.TreatNullsStyle.DoNotPaint;
fastLine.DataSource = points;
fastLine.Function = downSampling;
this.tChart1.Axes.Custom.Add(new Steema.TeeChart.Axis(this.tChart1.Chart));//
this.tChart1[1].CustomVertAxis = this.tChart1.Axes.Custom[0];//
this.tChart1[0].CustomVertAxis = this.tChart1.Axes.Custom[0];//
this.fastLine.Marks.Visible = true;//
}
private void CreateArrays()
{
int length = 2600000;
xValues = new Nullable<double>[length];
yValues = new Nullable<double>[length];
Random rnd = new Random();
for (int i = 0; i < length; i++)
{
xValues[i] = i;
yValues[i] = i;
}
}
private void tChart1_Zoomed(object sender, EventArgs e)
{
tChart1[1].CheckDataSource(); //series 1 is the function series
}
The DisplayedPointCount specifies how many points the DownSampling function should paint and displays this number as a maximum number of points. As I explained here, you may need to combine it with Tolerance property to get the results you expect. So, you could do something like this:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
InitializeChart();
}
private void InitializeChart()
{
//tChart1.Dock = DockStyle.Fill;
tChart1.Aspect.View3D = false;
tChart1.Zoomed += tChart1_Zoomed;
Steema.TeeChart.Styles.Points points1 = new Steema.TeeChart.Styles.Points(tChart1.Chart);
Random y = new Random();
for (int i = 0; i < 10000; i++)
{
points1.Add(DateTime.Now.AddHours(i), y.Next());
}
points1.XValues.DateTime = true;
points1.Pointer.HorizSize = 1;
points1.Pointer.VertSize = 1;
Steema.TeeChart.Functions.DownSampling downSampling1 = new Steema.TeeChart.Functions.DownSampling(tChart1.Chart);
downSampling1.Method = Steema.TeeChart.Functions.DownSamplingMethod.Average;
downSampling1.Tolerance = 100;
downSampling1.DisplayedPointCount = Convert.ToInt32(downSampling1.Tolerance * 4);
Steema.TeeChart.Styles.Line line1 = new Steema.TeeChart.Styles.Line(tChart1.Chart);
line1.Function = downSampling1;
line1.DataSource = points1;
line1.Marks.Visible = true;
line1.Marks.Style = MarksStyles.PointIndex;
UpdateTitle();
}
void tChart1_Zoomed(object sender, EventArgs e)
{
tChart1[1].CheckDataSource();
UpdateTitle();
}
private void UpdateTitle()
{
tChart1.Header.Text = (tChart1[1].Function as Steema.TeeChart.Functions.DownSampling).DisplayedPointCount.ToString();
}
}
I'm looking for the fastest way to refresh an image (and draw some shapes) on a Winform. I'm using a PictureBox now, but I'm open for suggestions.
The way I'm getting the max FPS possible I took from here: "My last post on render loops (hopefully)"
This is a game loop pattern, but it can also be used to other purpose, like to display live images acquired from a camera.
I'm drawing a red circle in different positions.
As you can see, the FPS drops a lot when a Bitmap is loaded at the PictureBox. Especially in the SizeMode Zoom (the one I want to use).
My PC values for FPS:
Form size (start size)
Bitmap ON: 140 (Zoom); 1000 (Normal); 135 (Stretch); 880 (Auto); 1000 (Center)
Bitmap OFF: 3400 !!
Form size (after Zoom 100% click)
Bitmap ON: 40 (Zoom); 150 (Normal); 65 (Stretch); 150 (Auto); 150 (Center)
Bitmap OFF: 540 !!
Edit 1:
Well, this results was for a 1024x1024 image. But I realizy that the form Height was not getting the right value, I found out that it is because the form size is limited by the Screen resolution. So I've edited the code to load a 800x600 Bitmap. Now the Zoom 100% button works. As you can see, at zoom 100% the FPS is 350, but if you increase the size of the PictureBox one more pixel, the FPS drops to 35, about 10x slower ¬¬ !
The big question is: How can I improve the FPS, specially in zoom mode?
PS: I know WinForm is not the best way to go, I also know WPF. But for now I'm looking the solution using WinForm. Ok? The reason is that I have a big scary project using it. I'm planing to move to WPF, but I'm still learning it. :)
Here is the full code, so you can test it by yourself.
Form1.cs:
//.NET 4.0 Client Profile
using System;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Windows.Forms;
//You need to add System.Activities.Presentation.dll
using System.Activities.Presentation.Hosting;
namespace WindowsFormsApplication2
{
public enum DrawSource
{
None = 0,
PictureBox = 1,
Grapghics = 2,
}
public partial class Form1 : Form
{
private readonly Timer _updateFPSTimer;
private bool _isIdle;
private Point _location;
private double _updateCount;
private readonly Bitmap _backImage;
public Form1()
{
InitializeComponent();
this.DoubleBuffered = this.ckbDoubleBufferForm.Checked;
this.pictureBox1.DoubleBuffered = this.ckbDoubleBufferPictureBox.Checked;
_backImage = new Bitmap(800, 600, PixelFormat.Format24bppRgb);
Graphics g = Graphics.FromImage(_backImage);
int penWidth = 10;
Pen pen = new Pen(Brushes.Blue, penWidth);
g.DrawRectangle(pen, new Rectangle(new Point(penWidth, penWidth), new Size(_backImage.Size.Width - 2 * penWidth, _backImage.Size.Height - 2 * penWidth)));
this.cbxSizeMode.DataSource = Enum.GetValues(typeof(PictureBoxSizeMode));
this.cbxSizeMode.SelectedItem = PictureBoxSizeMode.Zoom;
this.cbxBitmapDrawSource.DataSource = Enum.GetValues(typeof(DrawSource));
this.cbxBitmapDrawSource.SelectedItem = DrawSource.PictureBox;
this.pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
Application.Idle += Application_Idle;
_updateFPSTimer = new Timer();
_updateFPSTimer.Tick += UpdateFPSTimer_Tick;
_updateFPSTimer.Interval = Convert.ToInt32(1000.0 / 5); //Period in s = 1 s / 5 Hz
_updateFPSTimer.Start();
}
private void Application_Idle(object sender, EventArgs e)
{
while (this.ckbRun.Checked && IsAppStillIdle())
this.pictureBox1.Refresh();
}
void UpdateFPSTimer_Tick(object sender, EventArgs e)
{
GetFPS();
}
private void GetFPS()
{
double fps = _updateCount / (Convert.ToDouble(_updateFPSTimer.Interval) / 1000.0);
_updateCount = 0;
lblFps.Text = fps.ToString("0.00");
}
private void PictureBox1_Paint(object sender, PaintEventArgs e)
{
DrawCircle(e.Graphics);
}
private void DrawCircle(Graphics g)
{
if (this.pictureBox1.Image == null && ((DrawSource)this.cbxBitmapDrawSource.SelectedItem == DrawSource.Grapghics))
g.DrawImage(_backImage, 0, 0, g.ClipBounds.Width, g.ClipBounds.Height);
var rect = new Rectangle(_location, new Size(30, 30));
g.DrawEllipse(Pens.Red, rect);
_location.X += 1;
_location.Y += 1;
if (_location.X > g.ClipBounds.Width)
_location.X = 0;
if (_location.Y > g.ClipBounds.Height)
_location.Y = 0;
_updateCount++;
}
/// <summary>
/// Gets if the app still idle.
/// http://blogs.msdn.com/b/tmiller/archive/2005/05/05/415008.aspx
/// </summary>
/// <returns></returns>
private bool IsAppStillIdle()
{
Message msg;
return !PeekMessage(out msg, IntPtr.Zero, 0, 0, 0);
}
#region Unmanaged Get PeekMessage
// http://blogs.msdn.com/b/tmiller/archive/2005/05/05/415008.aspx
[System.Security.SuppressUnmanagedCodeSecurity] // We won't use this maliciously
[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern bool PeekMessage(out Message msg, IntPtr hWnd, uint messageFilterMin, uint messageFilterMax, uint flags);
#endregion
private void btnZoomReset_Click(object sender, EventArgs e)
{
if (_backImage != null)
{
//Any smarter way to do this?
//Note that the maximum Form size is limmited by designe by the Screen resolution.
//Rectangle screenRectangle = RectangleToScreen(this.ClientRectangle);
//int titleHeight = screenRectangle.Top - this.Top;
//Borders
Size border = new Size();
border.Width = this.Width - this.pictureBox1.Width;
border.Height = this.Height - this.pictureBox1.Height;
this.Width = border.Width + _backImage.Width;
this.Height = border.Height + _backImage.Height;
Console.WriteLine("PictureBox size: " + this.pictureBox1.Size.ToString());
}
}
private void SizeMode_SelectedIndexChanged(object sender, EventArgs e)
{
PictureBoxSizeMode mode;
Enum.TryParse<PictureBoxSizeMode>(cbxSizeMode.SelectedValue.ToString(), out mode);
this.pictureBox1.SizeMode = mode;
}
private void DoubleBufferForm_CheckedChanged(object sender, EventArgs e)
{
this.DoubleBuffered = this.ckbDoubleBufferForm.Checked;
}
private void DoubleBufferPictureBox_CheckedChanged(object sender, EventArgs e)
{
this.pictureBox1.DoubleBuffered = this.ckbDoubleBufferPictureBox.Checked;
}
private void BitmapDrawSource_SelectedIndexChanged(object sender, EventArgs e)
{
if ((DrawSource)this.cbxBitmapDrawSource.SelectedItem == DrawSource.PictureBox)
this.pictureBox1.Image = _backImage;
else
this.pictureBox1.Image = null;
}
}
}
Designer.CS:
namespace WindowsFormsApplication2
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.pictureBox1 = new WindowsFormsApplication2.PictureBoxDoubleBuffer();
this.label1 = new System.Windows.Forms.Label();
this.lblFps = new System.Windows.Forms.Label();
this.ckbRun = new System.Windows.Forms.CheckBox();
this.btnZoomReset = new System.Windows.Forms.Button();
this.label2 = new System.Windows.Forms.Label();
this.cbxSizeMode = new System.Windows.Forms.ComboBox();
this.gpbDoubleBuffer = new System.Windows.Forms.GroupBox();
this.ckbDoubleBufferPictureBox = new System.Windows.Forms.CheckBox();
this.ckbDoubleBufferForm = new System.Windows.Forms.CheckBox();
this.cbxBitmapDrawSource = new System.Windows.Forms.ComboBox();
this.label3 = new System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
this.gpbDoubleBuffer.SuspendLayout();
this.SuspendLayout();
//
// pictureBox1
//
this.pictureBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.pictureBox1.BackColor = System.Drawing.SystemColors.ControlDarkDark;
this.pictureBox1.DoubleBuffered = true;
this.pictureBox1.Location = new System.Drawing.Point(8, 84);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(347, 215);
this.pictureBox1.TabIndex = 0;
this.pictureBox1.TabStop = false;
this.pictureBox1.Paint += new System.Windows.Forms.PaintEventHandler(this.PictureBox1_Paint);
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(134, 13);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(30, 13);
this.label1.TabIndex = 3;
this.label1.Text = "FPS:";
//
// lblFps
//
this.lblFps.AutoSize = true;
this.lblFps.Location = new System.Drawing.Point(160, 13);
this.lblFps.Name = "lblFps";
this.lblFps.Size = new System.Drawing.Size(10, 13);
this.lblFps.TabIndex = 4;
this.lblFps.Text = "-";
//
// ckbRun
//
this.ckbRun.Appearance = System.Windows.Forms.Appearance.Button;
this.ckbRun.AutoSize = true;
this.ckbRun.Checked = true;
this.ckbRun.CheckState = System.Windows.Forms.CheckState.Checked;
this.ckbRun.Location = new System.Drawing.Point(8, 8);
this.ckbRun.Name = "ckbRun";
this.ckbRun.Size = new System.Drawing.Size(37, 23);
this.ckbRun.TabIndex = 5;
this.ckbRun.Text = "Run";
this.ckbRun.UseVisualStyleBackColor = true;
//
// btnZoomReset
//
this.btnZoomReset.Location = new System.Drawing.Point(51, 8);
this.btnZoomReset.Name = "btnZoomReset";
this.btnZoomReset.Size = new System.Drawing.Size(74, 23);
this.btnZoomReset.TabIndex = 7;
this.btnZoomReset.Text = "Zoom 100%";
this.btnZoomReset.UseVisualStyleBackColor = true;
this.btnZoomReset.Click += new System.EventHandler(this.btnZoomReset_Click);
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(5, 37);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(57, 13);
this.label2.TabIndex = 8;
this.label2.Text = "SizeMode:";
//
// cbxSizeMode
//
this.cbxSizeMode.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cbxSizeMode.FormattingEnabled = true;
this.cbxSizeMode.Location = new System.Drawing.Point(73, 34);
this.cbxSizeMode.Name = "cbxSizeMode";
this.cbxSizeMode.Size = new System.Drawing.Size(84, 21);
this.cbxSizeMode.TabIndex = 9;
this.cbxSizeMode.SelectedIndexChanged += new System.EventHandler(this.SizeMode_SelectedIndexChanged);
//
// gpbDoubleBuffer
//
this.gpbDoubleBuffer.Controls.Add(this.ckbDoubleBufferPictureBox);
this.gpbDoubleBuffer.Controls.Add(this.ckbDoubleBufferForm);
this.gpbDoubleBuffer.Location = new System.Drawing.Point(221, 8);
this.gpbDoubleBuffer.Name = "gpbDoubleBuffer";
this.gpbDoubleBuffer.Size = new System.Drawing.Size(99, 65);
this.gpbDoubleBuffer.TabIndex = 10;
this.gpbDoubleBuffer.TabStop = false;
this.gpbDoubleBuffer.Text = "Double Buffer";
//
// ckbDoubleBufferPictureBox
//
this.ckbDoubleBufferPictureBox.AutoSize = true;
this.ckbDoubleBufferPictureBox.Checked = true;
this.ckbDoubleBufferPictureBox.CheckState = System.Windows.Forms.CheckState.Checked;
this.ckbDoubleBufferPictureBox.Location = new System.Drawing.Point(9, 38);
this.ckbDoubleBufferPictureBox.Name = "ckbDoubleBufferPictureBox";
this.ckbDoubleBufferPictureBox.Size = new System.Drawing.Size(77, 17);
this.ckbDoubleBufferPictureBox.TabIndex = 8;
this.ckbDoubleBufferPictureBox.Text = "PictureBox";
this.ckbDoubleBufferPictureBox.UseVisualStyleBackColor = true;
this.ckbDoubleBufferPictureBox.CheckedChanged += new System.EventHandler(this.DoubleBufferPictureBox_CheckedChanged);
//
// ckbDoubleBufferForm
//
this.ckbDoubleBufferForm.AutoSize = true;
this.ckbDoubleBufferForm.Checked = true;
this.ckbDoubleBufferForm.CheckState = System.Windows.Forms.CheckState.Checked;
this.ckbDoubleBufferForm.Location = new System.Drawing.Point(9, 15);
this.ckbDoubleBufferForm.Name = "ckbDoubleBufferForm";
this.ckbDoubleBufferForm.Size = new System.Drawing.Size(49, 17);
this.ckbDoubleBufferForm.TabIndex = 7;
this.ckbDoubleBufferForm.Text = "Form";
this.ckbDoubleBufferForm.UseVisualStyleBackColor = true;
this.ckbDoubleBufferForm.CheckedChanged += new System.EventHandler(this.DoubleBufferForm_CheckedChanged);
//
// cbxBitmapDrawSource
//
this.cbxBitmapDrawSource.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cbxBitmapDrawSource.FormattingEnabled = true;
this.cbxBitmapDrawSource.Items.AddRange(new object[] {
"PictureBox",
"Graphics"});
this.cbxBitmapDrawSource.Location = new System.Drawing.Point(73, 57);
this.cbxBitmapDrawSource.Name = "cbxBitmapDrawSource";
this.cbxBitmapDrawSource.Size = new System.Drawing.Size(84, 21);
this.cbxBitmapDrawSource.TabIndex = 12;
this.cbxBitmapDrawSource.SelectedIndexChanged += new System.EventHandler(this.BitmapDrawSource_SelectedIndexChanged);
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(5, 60);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(68, 13);
this.label3.TabIndex = 11;
this.label3.Text = "Bitmap draw:";
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(361, 304);
this.Controls.Add(this.cbxBitmapDrawSource);
this.Controls.Add(this.label3);
this.Controls.Add(this.gpbDoubleBuffer);
this.Controls.Add(this.cbxSizeMode);
this.Controls.Add(this.label2);
this.Controls.Add(this.btnZoomReset);
this.Controls.Add(this.ckbRun);
this.Controls.Add(this.lblFps);
this.Controls.Add(this.label1);
this.Controls.Add(this.pictureBox1);
this.DoubleBuffered = true;
this.Name = "Form1";
this.Text = "Max FPS tester";
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
this.gpbDoubleBuffer.ResumeLayout(false);
this.gpbDoubleBuffer.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
PictureBoxDoubleBuffer pictureBox1;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label lblFps;
private System.Windows.Forms.CheckBox ckbRun;
private System.Windows.Forms.Button btnZoomReset;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.ComboBox cbxSizeMode;
private System.Windows.Forms.GroupBox gpbDoubleBuffer;
private System.Windows.Forms.CheckBox ckbDoubleBufferPictureBox;
private System.Windows.Forms.CheckBox ckbDoubleBufferForm;
private System.Windows.Forms.ComboBox cbxBitmapDrawSource;
private System.Windows.Forms.Label label3;
}
}
PictureBoxDoubleBuffer.cs:
using System.Windows.Forms;
namespace WindowsFormsApplication2
{
public class PictureBoxDoubleBuffer : PictureBox
{
public bool DoubleBuffered
{
get { return base.DoubleBuffered; }
set { base.DoubleBuffered = value; }
}
public PictureBoxDoubleBuffer()
{
base.DoubleBuffered = true;
}
}
}
"The big question is: How can I improve the FPS, specially in zoom mode?"
In Zoom (and Stretch) mode the Image() is probably being resized for each Refresh()...a very expensive operation. You could roll your own "zoom" mode that creates a new image that is already zoomed and assign that instead, leaving the mode at "Normal".
Here's a quick example using a cheat zoom with another PictureBox (obviously you could do the zoom mathematically by computing aspect ratio, etc...but that hurts my brain in the morning):
private void cbxSizeMode_SelectedIndexChanged(object sender, EventArgs e)
{
PictureBoxSizeMode mode;
Enum.TryParse<PictureBoxSizeMode>(cbxSizeMode.SelectedValue.ToString(), out mode);
this.pictureBox1.SizeMode = mode;
if (this.pictureBox1.SizeMode == PictureBoxSizeMode.Zoom)
{
using (PictureBox pb = new PictureBox())
{
pb.Size = pictureBox1.Size;
pb.SizeMode = PictureBoxSizeMode.Zoom;
pb.Image = _backImage;
Bitmap bmp = new Bitmap(pb.Size.Width, pb.Size.Height);
pb.DrawToBitmap(bmp, pb.ClientRectangle);
this.pictureBox1.SizeMode = PictureBoxSizeMode.Normal;
this.pictureBox1.Image = bmp;
}
}
else
{
pictureBox1.Image = _backImage;
}
}
You'll need to call this method when the form first runs if Zoom is the default selection, otherwise it won't have custom zoom image.
Now your Zoom mode should zoom along! (sorry, couldn't resist doing that)