I'm using a C# form and I essentially want to update a label for every second of the current time. Obviously the UI thread is getting in the way and stuff so I resorted to background workers and I'm sitting here scratching my head trying to update my label every second. I've tried using a while loop in several locations but it won't work. I'm obviously doing something wrong... Any solutions?
Code:
MainForm.Designer.cs:
using System;
namespace alarmClock
{
partial class MainForm
{
System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing) {
if (components != null) {
components.Dispose();
}
}
base.Dispose(disposing);
}
public static DateTime now = DateTime.Now;
public static string time = now.ToLongTimeString();
public void setRealHour() {
hour.Text = time[0].ToString() + time[1].ToString();
}
public void setRealMinute() {
minute.Text = time[3].ToString() + time[4].ToString();
}
public void setRealSecond() {
second.Text = time[6].ToString() + time[7].ToString();
}
public void setHourTime() {
setHour.Text = MainForm.setH.ToString();
if(MainForm.setH < 10) {
setHour.Text = "0" + MainForm.setH.ToString();
}
if(MainForm.setH > 24) {
MainForm.setH=0;
setHour.Text = "0" + MainForm.setH.ToString();
}
}
public void setMinuteTime() {
setMinute.Text = MainForm.setM.ToString();
if(MainForm.setM < 10) {
setMinute.Text = "0" + MainForm.setM.ToString();
}
if(MainForm.setM > 60) {
MainForm.setM=0;
setMinute.Text = "0" + MainForm.setM.ToString();
}
}
public void setSecondTime() {
setSecond.Text = MainForm.setS.ToString();
if(MainForm.setS < 10) {
setSecond.Text = "0" + MainForm.setS.ToString();
}
if(MainForm.setS > 60) {
MainForm.setS=0;
setSecond.Text = "0" + MainForm.setS.ToString();
}
}
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.minute = new System.Windows.Forms.Label();
this.hour = new System.Windows.Forms.Label();
this.second = new System.Windows.Forms.Label();
this.checkboxTime = new System.Windows.Forms.CheckedListBox();
this.delTime = new System.Windows.Forms.Button();
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel();
this.setHour = new System.Windows.Forms.Label();
this.setMinute = new System.Windows.Forms.Label();
this.setSecond = new System.Windows.Forms.Label();
this.tableLayoutPanel4 = new System.Windows.Forms.TableLayoutPanel();
this.subHour = new System.Windows.Forms.Button();
this.addHour = new System.Windows.Forms.Button();
this.subMin = new System.Windows.Forms.Button();
this.addMin = new System.Windows.Forms.Button();
this.subSec = new System.Windows.Forms.Button();
this.addSec = new System.Windows.Forms.Button();
this.setTime = new System.Windows.Forms.GroupBox();
this.addTime = new System.Windows.Forms.Button();
this.bgwM = new System.ComponentModel.BackgroundWorker();
this.bgwS = new System.ComponentModel.BackgroundWorker();
this.bgwH = new System.ComponentModel.BackgroundWorker();
this.tableLayoutPanel1.SuspendLayout();
this.tableLayoutPanel2.SuspendLayout();
this.tableLayoutPanel3.SuspendLayout();
this.tableLayoutPanel4.SuspendLayout();
this.setTime.SuspendLayout();
this.SuspendLayout();
//
// tableLayoutPanel1
//
resources.ApplyResources(this.tableLayoutPanel1, "tableLayoutPanel1");
this.tableLayoutPanel1.Controls.Add(this.minute, 1, 0);
this.tableLayoutPanel1.Controls.Add(this.hour, 0, 0);
this.tableLayoutPanel1.Controls.Add(this.second, 2, 0);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
//
// minute
//
resources.ApplyResources(this.minute, "minute");
this.minute.ForeColor = System.Drawing.Color.Black;
this.minute.Name = "minute";
//
// hour
//
resources.ApplyResources(this.hour, "hour");
this.hour.ForeColor = System.Drawing.Color.Black;
this.hour.Name = "hour";
//
// second
//
resources.ApplyResources(this.second, "second");
this.second.ForeColor = System.Drawing.Color.Black;
this.second.Name = "second";
//
// checkboxTime
//
this.checkboxTime.BackColor = System.Drawing.Color.Silver;
resources.ApplyResources(this.checkboxTime, "checkboxTime");
this.checkboxTime.ForeColor = System.Drawing.Color.Black;
this.checkboxTime.FormattingEnabled = true;
this.checkboxTime.Items.AddRange(new object[] {
resources.GetString("checkboxTime.Items"),
resources.GetString("checkboxTime.Items1")});
this.checkboxTime.Name = "checkboxTime";
this.checkboxTime.SelectedIndexChanged += new System.EventHandler(this.CheckboxTimeSelectedIndexChanged);
//
// delTime
//
resources.ApplyResources(this.delTime, "delTime");
this.delTime.Name = "delTime";
this.delTime.UseVisualStyleBackColor = true;
this.delTime.Click += new System.EventHandler(this.DelTimeClick);
//
// tableLayoutPanel2
//
resources.ApplyResources(this.tableLayoutPanel2, "tableLayoutPanel2");
this.tableLayoutPanel2.Controls.Add(this.tableLayoutPanel3, 0, 1);
this.tableLayoutPanel2.Controls.Add(this.tableLayoutPanel4, 0, 0);
this.tableLayoutPanel2.Name = "tableLayoutPanel2";
//
// tableLayoutPanel3
//
resources.ApplyResources(this.tableLayoutPanel3, "tableLayoutPanel3");
this.tableLayoutPanel3.Controls.Add(this.setHour, 0, 0);
this.tableLayoutPanel3.Controls.Add(this.setMinute, 1, 0);
this.tableLayoutPanel3.Controls.Add(this.setSecond, 2, 0);
this.tableLayoutPanel3.Name = "tableLayoutPanel3";
//
// setHour
//
resources.ApplyResources(this.setHour, "setHour");
this.setHour.ForeColor = System.Drawing.Color.Black;
this.setHour.Name = "setHour";
//
// setMinute
//
resources.ApplyResources(this.setMinute, "setMinute");
this.setMinute.ForeColor = System.Drawing.Color.Black;
this.setMinute.Name = "setMinute";
//
// setSecond
//
resources.ApplyResources(this.setSecond, "setSecond");
this.setSecond.ForeColor = System.Drawing.Color.Black;
this.setSecond.Name = "setSecond";
//
// tableLayoutPanel4
//
resources.ApplyResources(this.tableLayoutPanel4, "tableLayoutPanel4");
this.tableLayoutPanel4.Controls.Add(this.subHour, 0, 0);
this.tableLayoutPanel4.Controls.Add(this.addHour, 1, 0);
this.tableLayoutPanel4.Controls.Add(this.subMin, 2, 0);
this.tableLayoutPanel4.Controls.Add(this.addMin, 3, 0);
this.tableLayoutPanel4.Controls.Add(this.subSec, 4, 0);
this.tableLayoutPanel4.Controls.Add(this.addSec, 5, 0);
this.tableLayoutPanel4.Name = "tableLayoutPanel4";
//
// subHour
//
resources.ApplyResources(this.subHour, "subHour");
this.subHour.Name = "subHour";
this.subHour.UseVisualStyleBackColor = true;
this.subHour.Click += new System.EventHandler(this.SubHourClick);
//
// addHour
//
resources.ApplyResources(this.addHour, "addHour");
this.addHour.Name = "addHour";
this.addHour.UseVisualStyleBackColor = true;
this.addHour.Click += new System.EventHandler(this.AddHourClick);
//
// subMin
//
resources.ApplyResources(this.subMin, "subMin");
this.subMin.Name = "subMin";
this.subMin.UseVisualStyleBackColor = true;
this.subMin.Click += new System.EventHandler(this.SubMinClick);
//
// addMin
//
resources.ApplyResources(this.addMin, "addMin");
this.addMin.Name = "addMin";
this.addMin.UseVisualStyleBackColor = true;
this.addMin.Click += new System.EventHandler(this.AddMinClick);
//
// subSec
//
resources.ApplyResources(this.subSec, "subSec");
this.subSec.Name = "subSec";
this.subSec.UseVisualStyleBackColor = true;
this.subSec.Click += new System.EventHandler(this.SubSecClick);
//
// addSec
//
resources.ApplyResources(this.addSec, "addSec");
this.addSec.Name = "addSec";
this.addSec.UseVisualStyleBackColor = true;
this.addSec.Click += new System.EventHandler(this.AddSecClick);
//
// setTime
//
resources.ApplyResources(this.setTime, "setTime");
this.setTime.BackColor = System.Drawing.Color.Silver;
this.setTime.Controls.Add(this.addTime);
this.setTime.Controls.Add(this.tableLayoutPanel2);
this.setTime.Name = "setTime";
this.setTime.TabStop = false;
//
// addTime
//
resources.ApplyResources(this.addTime, "addTime");
this.addTime.Name = "addTime";
this.addTime.UseVisualStyleBackColor = true;
this.addTime.Click += new System.EventHandler(this.AddTimeClick);
//
// bgwM
//
this.bgwM.DoWork += new System.ComponentModel.DoWorkEventHandler(this.BgwMDoWork);
//
// bgwS
//
this.bgwS.DoWork += new System.ComponentModel.DoWorkEventHandler(this.BgwSDoWork);
//
// bgwH
//
this.bgwH.DoWork += new System.ComponentModel.DoWorkEventHandler(this.BgwHDoWork);
//
// MainForm
//
resources.ApplyResources(this, "$this");
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.DarkGray;
this.Controls.Add(this.setTime);
this.Controls.Add(this.delTime);
this.Controls.Add(this.checkboxTime);
this.Controls.Add(this.tableLayoutPanel1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.Name = "MainForm";
this.tableLayoutPanel1.ResumeLayout(false);
this.tableLayoutPanel1.PerformLayout();
this.tableLayoutPanel2.ResumeLayout(false);
this.tableLayoutPanel2.PerformLayout();
this.tableLayoutPanel3.ResumeLayout(false);
this.tableLayoutPanel3.PerformLayout();
this.tableLayoutPanel4.ResumeLayout(false);
this.setTime.ResumeLayout(false);
this.setTime.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
private System.ComponentModel.BackgroundWorker bgwH;
private System.ComponentModel.BackgroundWorker bgwS;
private System.ComponentModel.BackgroundWorker bgwM;
System.Windows.Forms.Button addTime;
System.Windows.Forms.GroupBox setTime;
System.Windows.Forms.Button addSec;
System.Windows.Forms.Button subSec;
System.Windows.Forms.Button addMin;
System.Windows.Forms.Button subMin;
System.Windows.Forms.Button addHour;
System.Windows.Forms.TableLayoutPanel tableLayoutPanel4;
System.Windows.Forms.Label setSecond;
System.Windows.Forms.Label setMinute;
System.Windows.Forms.Label setHour;
System.Windows.Forms.TableLayoutPanel tableLayoutPanel3;
System.Windows.Forms.Button subHour;
System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
System.Windows.Forms.Button delTime;
System.Windows.Forms.CheckedListBox checkboxTime;
System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
System.Windows.Forms.Label second;
System.Windows.Forms.Label hour;
System.Windows.Forms.Label minute;
void BgwHDoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
setRealHour();
}
void BgwMDoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
setRealMinute();
}
void BgwSDoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
setRealSecond();
}
}
}
MainForm.cs:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
namespace alarmClock
{
public partial class MainForm : Form
{
public static int setH = 0;
public static int setM = 0;
public static int setS = 0;
public MainForm()
{
InitializeComponent();
bgwH.RunWorkerAsync();
bgwM.RunWorkerAsync();
bgwS.RunWorkerAsync();
}
void DelTimeClick(object sender, EventArgs e)
{
}
void SubHourClick(object sender, EventArgs e)
{
setH--;
setHourTime();
}
void AddHourClick(object sender, EventArgs e)
{
setH++;
setHourTime();
}
void SubMinClick(object sender, EventArgs e)
{
setM--;
setMinuteTime();
}
void AddMinClick(object sender, EventArgs e)
{
setM++;
setMinuteTime();
}
void SubSecClick(object sender, EventArgs e)
{
setS--;
setSecondTime();
}
void AddSecClick(object sender, EventArgs e)
{
setS++;
setSecondTime();
}
void AddTimeClick(object sender, EventArgs e)
{
}
void CheckboxTimeSelectedIndexChanged(object sender, EventArgs e)
{
}
}
}
As Jeremy noted in the comments, a Timer would be a better choice.
For completeness, if you still wanted to use a BackgroundWorker, due to some other reason, you will need to use BackgroundWorker.ReportProgress() method. Any UI work must be done on the main UI thread. Using a BackgroundWorker you need to use the Reporting event handler to get your callback back on the main Thread.
You need to ensure BackgroundWorker.WorkerReportsProgress is set to TRUE. This is not by default. Then move your label set method into an Event Handler on ProgressChanged
Related
I have a simple winform application which allows users to drag controls to a tablelayoutpanel. But after some testing and trying to drag controls to a specific index row, I found out it doesn't work, not even with a hardcoded index number.
With the provided code example, I'm trying to add a textbox to row index 2, but when I drag content from the listbox to the tablelayoutpanel, it just adds the textbox in 'random' places as seen in the screenshot below
I expect the existing textboxes to shift down and make place for the textbox that's being added, as far as I understand from this: https://social.msdn.microsoft.com/Forums/windows/en-US/e4312cd8-6031-4a5c-92bf-e8adb1941fe5/insert-row-at-particular-position-in-table-layout-panel?forum=winforms.
Am I doing something wrong?
Designer code:
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.listBox1 = new System.Windows.Forms.ListBox();
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.SuspendLayout();
//
// listBox1
//
this.listBox1.FormattingEnabled = true;
this.listBox1.Location = new System.Drawing.Point(367, 12);
this.listBox1.Name = "listBox1";
this.listBox1.Size = new System.Drawing.Size(190, 407);
this.listBox1.TabIndex = 0;
this.listBox1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.listBox1_MouseDown);
//
// tableLayoutPanel1
//
this.tableLayoutPanel1.ColumnCount = 1;
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel1.Location = new System.Drawing.Point(13, 12);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.RowCount = 1;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel1.Size = new System.Drawing.Size(332, 407);
this.tableLayoutPanel1.TabIndex = 1;
this.tableLayoutPanel1.DragDrop += new System.Windows.Forms.DragEventHandler(this.tableLayoutPanel1_DragDrop);
this.tableLayoutPanel1.DragEnter += new System.Windows.Forms.DragEventHandler(this.tableLayoutPanel1_DragEnter);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(569, 431);
this.Controls.Add(this.tableLayoutPanel1);
this.Controls.Add(this.listBox1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.ListBox listBox1;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
}
Form code:
public partial class Form1 : Form
{
private int tempInt = 0;
public Form1()
{
InitializeComponent();
listBox1.Items.AddRange(new object[] { "test" });
tableLayoutPanel1.AllowDrop = true;
tableLayoutPanel1.GrowStyle = TableLayoutPanelGrowStyle.AddRows;
tableLayoutPanel1.AutoScroll = true;
tableLayoutPanel1.RowCount = 3;
}
private void listBox1_MouseDown(object sender, MouseEventArgs e)
{
tempInt++;
DoDragDrop("test" + tempInt, DragDropEffects.Copy);
}
private void tableLayoutPanel1_DragEnter(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Copy;
}
private void tableLayoutPanel1_DragDrop(object sender, DragEventArgs e)
{
string text = e.Data.GetData(typeof(String)) as string;
TextBox tb = new TextBox();
tb.Dock = DockStyle.Fill;
tb.Text = text;
// I want to add the textbox to the second row
tableLayoutPanel1.Controls.Add(tb, 0, 2);
tableLayoutPanel1.SetRow(tb, 2);
}
}
EDIT:
Added code based as DonBoitnott's suggested
private void tableLayoutPanel1_DragDrop(object sender, DragEventArgs e)
{
string text = e.Data.GetData(typeof(String)) as string;
TextBox tb = new TextBox();
tb.Dock = DockStyle.Fill;
tb.Text = text;
tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.AutoSize));
for (int i = 0; i < tableLayoutPanel1.Controls.Count; i++)
{
int pos = tableLayoutPanel1.GetRow(tableLayoutPanel1.Controls[i]);
if (pos > 1)
{
tableLayoutPanel1.SetRow(tableLayoutPanel1.Controls[i], pos + 1);
}
}
tableLayoutPanel1.Controls.Add(tb, 0, 2);
}
Give this modified form class a try, I've made a few changes throughout:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
listBox1.Items.AddRange(new Object[] { "TextBox" });
tableLayoutPanel1.AllowDrop = true;
tableLayoutPanel1.GrowStyle = TableLayoutPanelGrowStyle.AddRows;
tableLayoutPanel1.AutoScroll = true;
tableLayoutPanel1.RowStyles.Clear();
tableLayoutPanel1.ColumnStyles.Clear();
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100f));
}
private void listBox1_MouseDown(Object sender, MouseEventArgs e)
{
var count = tableLayoutPanel1.Controls.Count;
DoDragDrop($"test{count + 1}", DragDropEffects.Copy);
}
private void tableLayoutPanel1_DragEnter(Object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Copy;
}
private void tableLayoutPanel1_DragDrop(Object sender, DragEventArgs e)
{
var tb = new TextBox();
tb.Dock = DockStyle.Fill;
tb.Text = (e.Data.GetData(typeof(String)) as String);
var newRow = tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.AutoSize));
var ctrl = tableLayoutPanel1.GetChildAtPoint(tableLayoutPanel1.PointToClient(new Point(e.X, e.Y)));
if (ctrl != null)
{
var pos = tableLayoutPanel1.GetRow(ctrl);
for (Int32 i = tableLayoutPanel1.RowStyles.Count - 2; i >= pos; i--)
{
var c = tableLayoutPanel1.GetControlFromPosition(0, i);
if (c != null)
tableLayoutPanel1.SetRow(c, i + 1);
}
tableLayoutPanel1.Controls.Add(tb, 0, pos);
}
else
tableLayoutPanel1.Controls.Add(tb, 0, newRow);
}
}
The basic steps are:
Did I drop onto an existing control? If so, determine where.
If so, work bottom to top, moving each control down a slot. You must avoid overlapping, two controls cannot occupy the same cell.
If so, insert the new control into the newly emptied slot at the drop point.
If not, simply add the control at the end.
This is the first time I am working with drag and drop. So I have a form with a listbox and nothing else. I would like to be able to drag and drop files from desktop or windows explorer into my listbox. This is my code. What is missing?
Form:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void listBox1_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
e.Effect = DragDropEffects.All;
else
e.Effect = DragDropEffects.None;
}
private void listBox1_DragDrop(object sender, DragEventArgs e)
{
string[] s = (string[])e.Data.GetData(DataFormats.FileDrop, false);
int i;
for (i = 0; i < s.Length; i++)
listBox1.Items.Add(s[i]);
}
}
Form1.Designer.cs: (InitializeComponents)
private void InitializeComponent()
{
this.listBox1 = new System.Windows.Forms.ListBox();
this.SuspendLayout();
//
// listBox1
//
this.listBox1.AllowDrop = true;
this.listBox1.FormattingEnabled = true;
this.listBox1.Location = new System.Drawing.Point(30, 23);
this.listBox1.Name = "listBox1";
this.listBox1.Size = new System.Drawing.Size(376, 238);
this.listBox1.TabIndex = 0;
this.listBox1.DragDrop += new System.Windows.Forms.DragEventHandler(this.listBox1_DragDrop);
this.listBox1.DragEnter += new System.Windows.Forms.DragEventHandler(this.listBox1_DragEnter);
this.listBox1.DragOver += new System.Windows.Forms.DragEventHandler(this.listBox1_DragOver);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(438, 366);
this.Controls.Add(this.listBox1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
I make this and i think this will be OK.And no need DragOver.
private void listBox_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
e.Effect = DragDropEffects.All;
else
e.Effect = DragDropEffects.None;
}
private void listBox_DragDrop(object sender, DragEventArgs e)
{
if (listBox.Items.Count != 0)
{
listBox.Items.Clear();
}
string[] s = (string[])e.Data.GetData(DataFormats.FileDrop, false);
int i;
for (i = 0; i < s.Length; i++)
listBox.Items.Add(Path.GetFileName(s[i]));
}
i want print the content of panel with RadPrintPreview of telerik , but when i declare RadPrintDocument i cant associat this later with panel !
this is my code :
private void doc_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
Bitmap bmp = new Bitmap(radPanel2.Width, radPanel2.Height, radPanel2.CreateGraphics());
radPanel2.DrawToBitmap(bmp, new Rectangle(0, 0, radPanel2.Width, radPanel2.Height));
RectangleF bounds = e.PageSettings.PrintableArea;
e.Graphics.DrawImage(bmp, bounds.Left, bounds.Top, radPanel2.Width, radPanel2.Height);
}
private void btn_Imression_Click(object sender, EventArgs e)
{
System.Drawing.Printing.PrintDocument doc = new System.Drawing.Printing.PrintDocument();
doc.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(doc_PrintPage);
RadPrintPreviewDialog PrintSettings = new RadPrintPreviewDialog();
PrintSettings.Document = doc;
PageSettings pgsetting = new PageSettings();
if (PrintSettings.ShowDialog() == DialogResult.OK)
doc.Print();
}
and thank's for help :)
In order to print Telerik UI for WinForms control, you should use the embedded in the framework functionality, namely RadPrintDocument, which allows you to print any object implementing the IPrintable interface. Here is how this can be done for RadPanel:
RadPanel panel = new RadPanel();
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
InitializeComponent();
panel.Dock = DockStyle.Fill;
panel.BackColor = Color.Red;
panel.Parent = this;
RadButton b = new RadButton();
b.Text = "button1";
panel.Controls.Add(b);
RadButton b2 = new RadButton();
b2.Text = "button1";
b2.Location = new Point(400, 400);
panel.Controls.Add(b2);
}
private class PanelPrinter : IPrintable
{
private RadPanel panel;
public PanelPrinter(RadPanel panel)
{
this.panel = panel;
}
public int BeginPrint(RadPrintDocument sender, PrintEventArgs args)
{
return 1;
}
public bool EndPrint(RadPrintDocument sender, PrintEventArgs args)
{
return false;
}
public Form GetSettingsDialog(RadPrintDocument document)
{
return null;
}
public bool PrintPage(int pageNumber, RadPrintDocument sender, PrintPageEventArgs args)
{
float scale = Math.Min((float)args.MarginBounds.Width / panel.Size.Width, (float)args.MarginBounds.Height / panel.Size.Height);
Bitmap panelBmp = new Bitmap(this.panel.Width, this.panel.Height);
this.panel.DrawToBitmap(panelBmp, this.panel.Bounds);
Matrix saveMatrix = args.Graphics.Transform;
args.Graphics.ScaleTransform(scale, scale);
args.Graphics.DrawImage(panelBmp, args.MarginBounds.Location);
args.Graphics.Transform = saveMatrix;
return false;
}
}
private void radButton1_Click(object sender, EventArgs e)
{
RadPrintDocument document = new RadPrintDocument();
document.AssociatedObject = new PanelPrinter(this.panel);
RadPrintPreviewDialog dialog = new RadPrintPreviewDialog(document);
dialog.ShowDialog();
}
I want to try using several panels. But there is the error. When I click button_1, it should show one of the panel and hide another. I initialize my panels in Form_Load. Here is my code:
public partial class Form1 : Form
{
public Panel[] p = new Panel[2];
public int iter = 1;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (iter%2 == 1)
{
p[0].Visible = true;
p[1].Visible = false;
}
else if (iter%2 == 0)
{
p[0].Visible = false;
p[1].Visible = true;
}
iter++;
}
private void Form1_Load(object sender, EventArgs e)
{
for (int i = 0; i < 2; i++)
{
p[i] = new Panel();
p[i].Visible = false;
p[i].Size = new Size(200, 100);
p[i].Location = new Point(41, 103);
}
p[0].BackColor = System.Drawing.Color.Red;
p[1].BackColor = System.Drawing.Color.Blue;
}
}
private void Form1_Load(object sender, EventArgs e)
{
for (int i = 0; i < 2; i++)
{
p[i] = new Panel();
p[i].Visible = false;
p[i].Size = new Size(200, 100);
p[i].Location = new Point(41, 103);
this.Controls.Add(p[i]); // You need this line to add panel to form
}
p[0].BackColor = System.Drawing.Color.Red;
p[1].BackColor = System.Drawing.Color.Blue;
}
I was putting together a simple WinForm that would spawn a number of threads to loop from 0 to 10000 - the purpose of this - to slow down Windows to make some other programs run slow.
Basically the form has a text box that I want to write the loop index to from each thread. All was fine for a single thread, but since I have introduced more threads, I would appear to hang the application when I click on the Stop button - I am not too sure where to go from here.
My sample is probably not written well. I want to get a better understanding of multithreadding, deadlocks, etc. I have dabbled a little with BackgroundWorker in the past, but have been doing Java for the majority of the last 2+ years.
Form1.cs
public delegate void SetTextDelegate(string text);
public partial class Form1 : Form
{
private Thread[] _slow;
private object lockTextBox = new object();
public Form1()
{
InitializeComponent();
}
#region Event Handlers
private void ui_btnClose_Click(object sender, EventArgs e)
{
this.Close();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void ui_btnStart_Click(object sender, EventArgs e)
{
if (_slow != null)
{
StopAllThreads();
}
_slow = new Thread[ (int) numNoOfTheads.Value ];
for( int i = 0; i < numNoOfTheads.Value; i++)
{
_slow[i] = new Thread(ThreadRunLoop);
_slow[i].Start();
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (_slow != null)
{
StopAllThreads();
}
}
private void ui_btnStop_Click(object sender, EventArgs e)
{
if (_slow != null)
{
StopAllThreads();
}
}
private void ui_btnClear_Click(object sender, EventArgs e)
{
this.textBox1.Clear();
}
#endregion
protected void ThreadRunLoop()
{
try
{
for (int i = 0; i < 10000; i++)
{
UpdateText("Loop " + i + " for " + Thread.CurrentThread.ManagedThreadId);
}
}
catch (ThreadInterruptedException ex)
{
Console.WriteLine("Thread has been interrupted.");
}
}
private void UpdateText(string text)
{
//lock (lockTextBox)
//{
if (textBox1.InvokeRequired)
{
textBox1.Invoke(new SetTextDelegate(UpdateText), text);
}
else
{
textBox1.SuspendLayout();
textBox1.Text = textBox1.Text + text + System.Environment.NewLine;
textBox1.SelectionStart = textBox1.Text.Length;
textBox1.ScrollToCaret();
textBox1.ResumeLayout();
}
//}
}
private void StopAllThreads()
{
for (int i = 0; i < _slow.Length; i++)
{
if (_slow[i] != null)
{
_slow[i].Interrupt();
_slow[i] = null;
}
}
_slow = null;
}
}
Form1.Designer.cs
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.ui_btnClose = new System.Windows.Forms.Button();
this.ui_btnStart = new System.Windows.Forms.Button();
this.ui_btnStop = new System.Windows.Forms.Button();
this.textBox1 = new System.Windows.Forms.TextBox();
this.ui_btnClear = new System.Windows.Forms.Button();
this.numNoOfTheads = new System.Windows.Forms.NumericUpDown();
this.label1 = new System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize)(this.numNoOfTheads)).BeginInit();
this.SuspendLayout();
//
// ui_btnClose
//
this.ui_btnClose.Location = new System.Drawing.Point(433, 268);
this.ui_btnClose.Name = "ui_btnClose";
this.ui_btnClose.Size = new System.Drawing.Size(75, 23);
this.ui_btnClose.TabIndex = 0;
this.ui_btnClose.Text = "Close";
this.ui_btnClose.UseVisualStyleBackColor = true;
this.ui_btnClose.Click += new System.EventHandler(this.ui_btnClose_Click);
//
// ui_btnStart
//
this.ui_btnStart.Location = new System.Drawing.Point(12, 12);
this.ui_btnStart.Name = "ui_btnStart";
this.ui_btnStart.Size = new System.Drawing.Size(75, 23);
this.ui_btnStart.TabIndex = 1;
this.ui_btnStart.Text = "Start";
this.ui_btnStart.UseVisualStyleBackColor = true;
this.ui_btnStart.Click += new System.EventHandler(this.ui_btnStart_Click);
//
// ui_btnStop
//
this.ui_btnStop.Location = new System.Drawing.Point(12, 41);
this.ui_btnStop.Name = "ui_btnStop";
this.ui_btnStop.Size = new System.Drawing.Size(75, 23);
this.ui_btnStop.TabIndex = 2;
this.ui_btnStop.Text = "Stop";
this.ui_btnStop.UseVisualStyleBackColor = true;
this.ui_btnStop.Click += new System.EventHandler(this.ui_btnStop_Click);
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(93, 12);
this.textBox1.Multiline = true;
this.textBox1.Name = "textBox1";
this.textBox1.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.textBox1.Size = new System.Drawing.Size(415, 241);
this.textBox1.TabIndex = 3;
//
// ui_btnClear
//
this.ui_btnClear.Location = new System.Drawing.Point(352, 268);
this.ui_btnClear.Name = "ui_btnClear";
this.ui_btnClear.Size = new System.Drawing.Size(75, 23);
this.ui_btnClear.TabIndex = 4;
this.ui_btnClear.Text = "Clear";
this.ui_btnClear.UseVisualStyleBackColor = true;
this.ui_btnClear.Click += new System.EventHandler(this.ui_btnClear_Click);
//
// numNoOfTheads
//
this.numNoOfTheads.Location = new System.Drawing.Point(12, 98);
this.numNoOfTheads.Name = "numNoOfTheads";
this.numNoOfTheads.Size = new System.Drawing.Size(74, 20);
this.numNoOfTheads.TabIndex = 5;
this.numNoOfTheads.Value = new decimal(new int[] {
1,
0,
0,
0});
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(9, 82);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(83, 13);
this.label1.TabIndex = 6;
this.label1.Text = "No. Of Threads:";
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(520, 303);
this.Controls.Add(this.label1);
this.Controls.Add(this.numNoOfTheads);
this.Controls.Add(this.ui_btnClear);
this.Controls.Add(this.textBox1);
this.Controls.Add(this.ui_btnStop);
this.Controls.Add(this.ui_btnStart);
this.Controls.Add(this.ui_btnClose);
this.Name = "Form1";
this.Text = "Slow My Machine";
this.Load += new System.EventHandler(this.Form1_Load);
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
((System.ComponentModel.ISupportInitialize)(this.numNoOfTheads)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button ui_btnClose;
private System.Windows.Forms.Button ui_btnStart;
private System.Windows.Forms.Button ui_btnStop;
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.Button ui_btnClear;
private System.Windows.Forms.NumericUpDown numNoOfTheads;
private System.Windows.Forms.Label label1;
}
Update
If I move the lock to the else in the UpdateText method and add a Thread.Sleep(20); in the loop, then my GUI is more responsive and I can click on the Stop button and move the form around.
Any feedback, fixes will be appreciated.
The lock inside UpdateText will cause a deadlock. The worker thread acquires the lock and then calls Invoke. The UI thread then calls tries to acquire the same lock, but has to wait until it is released. The thing is that the lock will never get released because Invoke blocks until the UI thread has finished executing the delegate. That never happens because the UI thread is still waiting to acquire the lock. Deadlock!
Change the for loop to
for (int i = 0; i < 10000; i++)
{
var text = "Loop " + i + " for " + Thread.CurrentThread.ManagedThreadId;
if (textBox1.InvokeRequired)
textBox1.Invoke(new SetTextDelegate(UpdateText), text);
else
UpdateText(text);
}
And change the UpdateText to
private void UpdateText(string text)
{
textBox1.SuspendLayout();
textBox1.Text = textBox1.Text + text + System.Environment.NewLine;
textBox1.SelectionStart = textBox1.Text.Length;
textBox1.ScrollToCaret();
textBox1.ResumeLayout();
}
EDIT: My mistake. This will just improve the organization and not in any aspect. If you want to update the UI so frequently you should use BackgroundWorker what rdkleine said.
Try moving the lock in UpdateText to inside the else.
Use a BackgroundWorker which updates the UI thread.
Here a good example how to use the BackgroundWorker:
http://msdn.microsoft.com/en-us/library/cc221403(v=vs.95).aspx
It doesn't explain how to retrieve the data (your int value) and put it in a textbox but it is a good start.