Resize image included in button when resize - c#

I have a button with an included image and a text :
When I resize my application, I resize the label to fit with the new button's height but the image is not resized :
I saw a solution is to set image to BackgroundImage but it does not match the design of my button :
this.buttonClose.Dock = System.Windows.Forms.DockStyle.Fill;
this.buttonClose.Image = ((System.Drawing.Image)(resources.GetObject("buttonClose.Image")));
this.buttonClose.Name = "buttonClose";
this.buttonClose.Size = new System.Drawing.Size(482, 28);
this.buttonClose.Text = "Close";
this.buttonClose.TextAlign = ContentAlignment.MiddleRight;
this.buttonClose.TextImageRelation = TextImageRelation.ImageBeforeText;
this.buttonClose.UseVisualStyleBackColor = true;
this.buttonClose.Click += new System.EventHandler(this.buttonClose_Click);

if you want to automatically resize the application use this method
create class called resize
and paste this code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace YOUR APPLICATION NAMESPACE
{
public class ClassResize
{
List<System.Drawing.Rectangle> AryControlsStorage = new List<System.Drawing.Rectangle>();
private bool ShowRowHeader=false;
private Form form { get; set; }
private float FontSize { get; set; }
private System.Drawing.SizeF FormSize { get; set; }
public ClassResize(Form FForm)
{
form = FForm;
FormSize = FForm.ClientSize;
FontSize = FForm.Font.Size;
}
private static IEnumerable<Control> GetAllControls(Control c)
{
return c.Controls.Cast<Control>().SelectMany(item=>
GetAllControls(item)).Concat(c.Controls.Cast<Control>()).Where(control=>
control.Name !=string.Empty);
}
public void GetInitialSize()
{
var _Controls = GetAllControls(form);
foreach (Control control in _Controls)
{
AryControlsStorage.Add(control.Bounds);
if (control.GetType() == typeof(DataGridView))
DGColumnAdjust(((DataGridView)control), ShowRowHeader);
}
}
public void Resize()
{
double FormRatioWidth = (double)form.ClientSize.Width / (double)FormSize.Width;
double FormRatioHeight=(double)form.ClientSize.Height / (double)FormSize.Height;
var _Controls = GetAllControls(form);
int Postion = -1;
foreach(Control control in _Controls)
{
Postion += 1;
System.Drawing.Size _ControlsSize = new System.Drawing.Size((int)(AryControlsStorage[Postion].Width * FormRatioWidth),
(int)(AryControlsStorage[Postion].Height * FormRatioHeight));
System.Drawing.Point _ControlsPoint = new System.Drawing.Point((int)(AryControlsStorage[Postion].X * FormRatioWidth),
(int)(AryControlsStorage[Postion].Y * FormRatioHeight));
control.Bounds = new System.Drawing.Rectangle(_ControlsPoint, _ControlsSize);
if (control.GetType() == typeof(DataGridView))
DGColumnAdjust(((DataGridView)control),ShowRowHeader);
//control.Font = new System.Drawing.Font(form.Font.FontFamily,
//(float)(((Convert.ToDouble(FontSize) * FormRatioWidth) / 1.5) + ((Convert.ToDouble(FontSize) * FormRatioHeight) / 1.5)));
}
}
private void DGColumnAdjust(DataGridView dgv, bool _showRowHeader)
{
int intRowHeader = 0;
const int Hscrolbarwidth = 5;
if (_showRowHeader)
{
intRowHeader = dgv.RowHeadersWidth;
}
else
{
dgv.RowHeadersVisible = false;
}
for (int i = 0; i < dgv.ColumnCount; i++)
{
if (dgv.Dock == DockStyle.Fill)
dgv.Columns[i].Width = ((dgv.Width - intRowHeader) / dgv.ColumnCount);
else
dgv.Columns[i].Width = ((dgv.Width - intRowHeader - Hscrolbarwidth) / dgv.ColumnCount);
}
}
}
}
and call this class in you form
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Common;
using System.Data.SqlClient;
namespace YOUR NAMESPACE
{
public partial class FORMNAME: Form
{
ClassResize Form;
public FORMNAME()
{
InitializeComponent();
Form = new ClassResize(this);
}
}
}
this will automatically resize your all controls in forms

Finally found a solution, maybe not the best but working fine :
private Dictionary<Button, Image> dicButtonsBaseImage = new Dictionary<Button, Image>();
private void SetImageButton(Button btn, Image img)
{
// Initiate image for button
btn.Image = img;
// set method dor sizeChanged
btn.SizeChanged += Control_SizeChanged;
// Save image associated for this button
if (!dicButtonsBaseImage.ContainsKey(btn))
dicButtonsBaseImage.Add(btn, img);
else
dicButtonsBaseImage[btn] = img;
// Init image size
resizeImageSize(btn);
}
private void Control_SizeChanged(object sender, EventArgs e)
{
Control c = sender as Control;
if (c != null)
{
Button b = sender as Button;
if (b != null)
{
resizeImageSize(b);
}
}
}
private static void resizeImageSize(Button b)
{
if (b.Image != null && dicButtonsBaseImage.ContainsKey(b))
{
// Set a margin (top/bot) to 8px
if (b.Height - 8 < dicButtonsBaseImage[b].Height)
{
int newHeight = b.Height - 8;
if (newHeight <= 0)
newHeight = 1;
Image img = new Bitmap(dicButtonsBaseImage[b], new Size(dicButtonsBaseImage[b].Width, newHeight));
b.Image = img;
}
else
{
b.Image = dicButtonsBaseImage[b];
}
}
}

Related

MaterialSkin Right to Left custom Control

I'm using MaterialSkin UI controls , how can I change the control properties to Right to left, because it's by default Left to Right.
I think this is the code should be edited :
private void UpdateTabRects()
{
_tabRects = new List<Rectangle>();
//If there isn't a base tab control, the rects shouldn't be calculated
//If there aren't tab pages in the base tab control, the list should just be empty which has been set already; exit the void
if (_baseTabControl == null || _baseTabControl.TabCount == 0) return;
//Calculate the bounds of each tab header specified in the base tab control
using (var b = new Bitmap(1, 1))
{
using (var g = Graphics.FromImage(b))
{
_tabRects.Add(new Rectangle(SkinManager.FormPadding, 0, TabHeaderPadding * 2 + (int)g.MeasureString(_baseTabControl.TabPages[0].Text, SkinManager.Font_Size11).Width, Height));
for (int i = 1; i < _baseTabControl.TabPages.Count; i++)
{
_tabRects.Add(new Rectangle(_tabRects[i - 1].Right, 0, TabHeaderPadding * 2 + (int)g.MeasureString(_baseTabControl.TabPages[i].Text , SkinManager.Font_Size11).Width , Height));
}
}
}
}
and this is the full code for the control :
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Text;
using System.Windows.Forms;
using MaterialSkin.Animations;
namespace MaterialSkin.Controls
{
public class MaterialTabSelector : Control, IMaterialControl
{
[Browsable(false)]
public int Depth { get; set; }
[Browsable(false)]
public MaterialSkinManager SkinManager => MaterialSkinManager.Instance;
[Browsable(false)]
public MouseState MouseState { get; set; }
private MaterialTabControl _baseTabControl;
public MaterialTabControl BaseTabControl
{
get { return _baseTabControl; }
set
{
_baseTabControl = value;
if (_baseTabControl == null) return;
_previousSelectedTabIndex = _baseTabControl.SelectedIndex;
_baseTabControl.Deselected += (sender, args) =>
{
_previousSelectedTabIndex = _baseTabControl.SelectedIndex;
};
_baseTabControl.SelectedIndexChanged += (sender, args) =>
{
_animationManager.SetProgress(0);
_animationManager.StartNewAnimation(AnimationDirection.In);
};
_baseTabControl.ControlAdded += delegate
{
Invalidate();
};
_baseTabControl.ControlRemoved += delegate
{
Invalidate();
};
}
}
private int _previousSelectedTabIndex;
private Point _animationSource;
private readonly AnimationManager _animationManager;
private List<Rectangle> _tabRects;
private const int TabHeaderPadding = 24;
private const int TabIndicatorHeight = 2;
public MaterialTabSelector()
{
SetStyle(ControlStyles.DoubleBuffer | ControlStyles.OptimizedDoubleBuffer, true);
Height = 48;
_animationManager = new AnimationManager
{
AnimationType = AnimationType.EaseOut,
Increment = 0.04
};
_animationManager.OnAnimationProgress += sender => Invalidate();
}
protected override void OnPaint(PaintEventArgs e)
{
var g = e.Graphics;
g.TextRenderingHint = TextRenderingHint.AntiAlias;
g.Clear(SkinManager.ColorScheme.PrimaryColor);
if (_baseTabControl == null) return;
if (!_animationManager.IsAnimating() || _tabRects == null || _tabRects.Count != _baseTabControl.TabCount)
UpdateTabRects();
var animationProgress = _animationManager.GetProgress();
//Click feedback
if (_animationManager.IsAnimating())
{
var rippleBrush = new SolidBrush(Color.FromArgb((int)(51 - (animationProgress * 50)), Color.White));
var rippleSize = (int)(animationProgress * _tabRects[_baseTabControl.SelectedIndex].Width * 1.75);
g.SetClip(_tabRects[_baseTabControl.SelectedIndex]);
g.FillEllipse(rippleBrush, new Rectangle(_animationSource.X - rippleSize / 2, _animationSource.Y - rippleSize / 2, rippleSize, rippleSize));
g.ResetClip();
rippleBrush.Dispose();
}
//Draw tab headers
foreach (TabPage tabPage in _baseTabControl.TabPages)
{
var currentTabIndex = _baseTabControl.TabPages.IndexOf(tabPage);
Brush textBrush = new SolidBrush(Color.FromArgb(CalculateTextAlpha(currentTabIndex, animationProgress), SkinManager.ColorScheme.TextColor));
g.DrawString(tabPage.Text.ToUpper(), SkinManager.Font_Size11, textBrush, _tabRects[currentTabIndex], new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
textBrush.Dispose();
}
//Animate tab indicator
var previousSelectedTabIndexIfHasOne = _previousSelectedTabIndex == -1 ? _baseTabControl.SelectedIndex : _previousSelectedTabIndex;
var previousActiveTabRect = _tabRects[previousSelectedTabIndexIfHasOne];
var activeTabPageRect = _tabRects[_baseTabControl.SelectedIndex];
var y = activeTabPageRect.Bottom - 2;
var x = previousActiveTabRect.X + (int)((activeTabPageRect.X - previousActiveTabRect.X) * animationProgress);
var width = previousActiveTabRect.Width + (int)((activeTabPageRect.Width - previousActiveTabRect.Width) * animationProgress);
g.FillRectangle(SkinManager.ColorScheme.AccentBrush, x, y, width, TabIndicatorHeight);
}
private int CalculateTextAlpha(int tabIndex, double animationProgress)
{
int primaryA = SkinManager.ActionBarText.A;
int secondaryA = SkinManager.ActionBarTextSecondary.A;
if (tabIndex == _baseTabControl.SelectedIndex && !_animationManager.IsAnimating())
{
return primaryA;
}
if (tabIndex != _previousSelectedTabIndex && tabIndex != _baseTabControl.SelectedIndex)
{
return secondaryA;
}
if (tabIndex == _previousSelectedTabIndex)
{
return primaryA - (int)((primaryA - secondaryA) * animationProgress);
}
return secondaryA + (int)((primaryA - secondaryA) * animationProgress);
}
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
if (_tabRects == null) UpdateTabRects();
for (var i = 0; i < _tabRects.Count; i++)
{
if (_tabRects[i].Contains(e.Location))
{
_baseTabControl.SelectedIndex = i;
}
}
_animationSource = e.Location;
}
private void UpdateTabRects()
{
_tabRects = new List<Rectangle>();
//If there isn't a base tab control, the rects shouldn't be calculated
//If there aren't tab pages in the base tab control, the list should just be empty which has been set already; exit the void
if (_baseTabControl == null || _baseTabControl.TabCount == 0) return;
//Calculate the bounds of each tab header specified in the base tab control
using (var b = new Bitmap(1, 1))
{
using (var g = Graphics.FromImage(b))
{
_tabRects.Add(new Rectangle(SkinManager.FormPadding, 0, TabHeaderPadding * 2 + (int)g.MeasureString(_baseTabControl.TabPages[0].Text, SkinManager.Font_Size11).Width, Height));
for (int i = 1; i < _baseTabControl.TabPages.Count; i++)
{
_tabRects.Add(new Rectangle(_tabRects[i - 1].Right, 0, TabHeaderPadding * 2 + (int)g.MeasureString(_baseTabControl.TabPages[i].Text , SkinManager.Font_Size11).Width , Height));
}
}
}
}
}
}
If you're using windows forms you would go into the properties of the tab control and make:
RightToLeft = Yes
and
RightToLeftLayout = True.
This is also a duplicate question:
How to make Managed Tab Control (MTC) appear right to left

C# Accessing Dynamic Controls Windows Forms

I am creating a number of comboBoxes based on user input. I create the boxes just fine, but when it comes to wanting to check the text within them I am struggling.
I thought of maybe storing them in a IList but that hasn't seemed to work so far. The goal is to change the text of all of them on a button click, but after several attempts I am becoming frustrated.
IList<ComboBox> comboBoxes = new List<ComboBox>();
private void AddComboBox(int i)
{
var comboBoxStudentAttendance = new ComboBox();
comboBoxStudentAttendance.Top = TopMarginDistance(i);
comboBoxStudentAttendance.Items.Add("");
comboBoxStudentAttendance.Items.Add("Present");
comboBoxStudentAttendance.Items.Add("Absent");
comboBoxStudentAttendance.Items.Add("Late");
comboBoxStudentAttendance.Items.Add("Sick");
comboBoxStudentAttendance.Items.Add("Excused");
comboBoxes.Add(comboBoxStudentAttendance);
this.Controls.Add(comboBoxStudentAttendance);
}
I tried the following but with no success.
private void DistributeAttendanceButton_Click(object sender, EventArgs e)
{
for (int i = 0; i < sampleNum; i++)
{
switch (MasterComboBox.Text)
{
case "Present":
comboBoxes.ElementAt(i).Text = "Present";
break;
}
}
}
Try this
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
const int TOP_MARGIN = 10;
const int LEFT_MARGIN = 10;
const int WIDTH = 200;
const int HEIGHT = 10;
const int SPACE = 15;
const int NUMBER_OF_BOXES = 10;
public Form1()
{
InitializeComponent();
MasterComboBox.Text = "Present";
for (int i = 0; i < NUMBER_OF_BOXES; i++)
{
AddComboBox(i);
}
}
List<ComboBox> comboBoxes = new List<ComboBox>();
private void AddComboBox(int i)
{
var comboBoxStudentAttendance = new ComboBox();
comboBoxStudentAttendance.Top = TOP_MARGIN + i * (SPACE + HEIGHT);
comboBoxStudentAttendance.Left = LEFT_MARGIN;
comboBoxStudentAttendance.Width = WIDTH;
comboBoxStudentAttendance.Height = HEIGHT;
comboBoxStudentAttendance.Items.Add("");
comboBoxStudentAttendance.Items.Add("Present");
comboBoxStudentAttendance.Items.Add("Absent");
comboBoxStudentAttendance.Items.Add("Late");
comboBoxStudentAttendance.Items.Add("Sick");
comboBoxStudentAttendance.Items.Add("Excused");
comboBoxes.Add(comboBoxStudentAttendance);
this.Controls.Add(comboBoxStudentAttendance);
}
private void DistributeAttendanceButton_Click(object sender, EventArgs e)
{
for (int i = 0; i < comboBoxes.Count; i++)
{
switch (MasterComboBox.Text)
{
case "Present":
comboBoxes[i].Text = "Present";
break;
}
}
}
}
}

How can i pass and update in real time from a new form the pictureBox1 in form1?

I added a new form to my project the new form contain in the designer webBrowser control. What i'm doing is parsing from html some links then navigate to each link then taking a screenshot and save to the hard disk each image i navigated to in the webBrowser.
In the end when all the links navigated and i have the images on the hard disk i display them on Form1 pictureBox with a hScrollBar.
But now instead waiting for it to finish in the new form and then to show all the images i want to show each saved image on the hard disk in the pictureBox in form1.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.IO;
namespace WebBrowserScreenshots.cs
{
public partial class WebBrowserScreenshots : Form
{
private class MyComparer : IComparer<string>
{
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
private static extern int StrCmpLogicalW(string x, string y);
public int Compare(string x, string y)
{
return StrCmpLogicalW(x, y);
}
}
List<string> newHtmls = new List<string>();
string uri = "";
public bool htmlloaded = false;
int countlinks = 0;
public int numberoflinks = 0;
public int numberofimages = 0;
public List<string> imageList = new List<string>();
public WebBrowserScreenshots()
{
InitializeComponent();
webBrowser1.ScrollBarsEnabled = false;
webBrowser1.ScriptErrorsSuppressed = true;
NavigateToSites();
}
string test;
List<string> htmls;
private void GetLinks()
{
htmlloaded = true;
for (int i = 1; i < 304; i++)
{
if (newHtmls.Count == 1)
break;
backgroundWorker1.ReportProgress(i);
HtmlAgilityPack.HtmlWeb hw = new HtmlAgilityPack.HtmlWeb();
HtmlAgilityPack.HtmlDocument doc = hw.Load("http://test/page" + i);
htmls = new List<string>();
foreach (HtmlAgilityPack.HtmlNode link in doc.DocumentNode.SelectNodes("//a[#href]"))
{
string hrefValue = link.GetAttributeValue("href", string.Empty);
if (hrefValue.Contains("http") && hrefValue.Contains("attachment"))
htmls.Add(hrefValue);
}
if (htmls.Count > 0 && abovezero == false)
RealTimeHtmlList();
}
}
bool abovezero = false;
private void RealTimeHtmlList()
{
abovezero = true;
for (int x = 0; x < htmls.Count; x++)
{
test = htmls[x];
int index = test.IndexOf("amp");
string test1 = test.Substring(39, index - 25);
test = test.Remove(39, index - 35);
int index1 = test.IndexOf("amp");
if (index1 > 0)
test = test.Remove(index1, 4);
if (!newHtmls.Contains(test))
{
while (true)
{
if (htmlloaded == true)
{
newHtmls.Add(test);
RealTimeNavigate(test);
}
else
{
break;
}
}
}
}
}
private void RealTimeNavigate(string tests)
{
uri = test;
webBrowser1.Navigate(test);
htmlloaded = false;
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
GetLinks();
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
numberoflinks = e.ProgressPercentage;
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
numberofimages = newHtmls.Count;
htmlloaded = true;
}
private void NavigateToLinks()
{
if (countlinks != newHtmls.Count)
{
while (true)
{
if (htmlloaded == true)
{
uri = newHtmls[countlinks];
webBrowser1.Navigate(newHtmls[countlinks]);
countlinks++;
htmlloaded = false;
}
else
{
break;
}
}
}
}
int imagescount = 0;
public FileInfo[] filesinfo;
public bool savedall = false;
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
if (e.Url.ToString() == uri)
{
Bitmap bmp = new Bitmap(SaveImageFromWebBrowser(webBrowser1));
bmp = ImageTrim.ImagesTrim(bmp);
bmp.Save(#"e:\webbrowserimages\Image" + imagescount.ToString() + ".bmp",
System.Drawing.Imaging.ImageFormat.Bmp);
bmp.Dispose();
imagescount++;
htmlloaded = true;
RealTimeHtmlList();
}
}
private void NavigateToSites()
{
backgroundWorker1.RunWorkerAsync();
}
[DllImport("user32.dll")]
public static extern bool PrintWindow(IntPtr hwnd, IntPtr hdcBlt, uint nFlags);
private Bitmap SaveImageFromWebBrowser(Control ctl)
{
Bitmap bmp = new Bitmap(ctl.ClientRectangle.Width, ctl.ClientRectangle.Height);
using (Graphics graphics = Graphics.FromImage(bmp))
{
IntPtr hDC = graphics.GetHdc();
try { PrintWindow(ctl.Handle, hDC, (uint)0); }
finally { graphics.ReleaseHdc(hDC); }
}
return bmp;
}
}
}
And in form1 i did:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Runtime.InteropServices;
namespace WebBrowserScreenshots.cs
{
public partial class Form1 : Form
{
private class MyComparer : IComparer<string>
{
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
private static extern int StrCmpLogicalW(string x, string y);
public int Compare(string x, string y)
{
return StrCmpLogicalW(x, y);
}
}
public List<string> imageList = new List<string>();
List<string> numbers = new List<string>();
WebBrowserScreenshots wbss;
public Form1()
{
InitializeComponent();
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
this.imageList = Directory.GetFiles(#"e:\webbrowserimages\", "*.bmp").ToList();
this.imageList.Sort(new MyComparer());
if (this.imageList.Count > 0)
{
hScrollBar1.Minimum = 0;
hScrollBar1.Value = 0;
hScrollBar1.Maximum = this.imageList.Count - 1;
hScrollBar1.SmallChange = 1;
hScrollBar1.LargeChange = 1;
pictureBox1.Image = Image.FromFile(this.imageList[0]);
}
else
{
timer1.Start();
wbss = new WebBrowserScreenshots();
wbss.Show();
}
}
FileInfo[] myFile;
private void timer1_Tick(object sender, EventArgs e)
{
if (wbss.savedall == true)
{
timer1.Stop();
hScrollBar1.Enabled = true;
hScrollBar1.Minimum = 0;
hScrollBar1.Value = 0;
hScrollBar1.Maximum = wbss.imageList.Count - 1;
hScrollBar1.SmallChange = 1;
hScrollBar1.LargeChange = 1;
pictureBox1.Image = Image.FromFile(wbss.imageList[0]);
}
else
{
if (wbss.htmlloaded == true)
{
var directory = new DirectoryInfo(#"e:\webbrowserimages\");
myFile = directory.GetFiles("*.bmp");
if (myFile.Length > 0)
{
var myFiles = (from f in directory.GetFiles("*.bmp")
orderby f.LastWriteTime descending
select f).First();
hScrollBar1.Enabled = true;
hScrollBar1.Minimum = 0;
hScrollBar1.Value = 0;
hScrollBar1.Maximum = 1;
hScrollBar1.SmallChange = 1;
hScrollBar1.LargeChange = 1;
pictureBox1.Image = Image.FromFile(myFiles.Name);
}
}
}
}
private void hScrollBar1_Scroll(object sender, ScrollEventArgs e)
{
int index = (int)hScrollBar1.Value;
if (pictureBox1.Image != null) pictureBox1.Image.Dispose();
if (this.imageList.Count > 0)
{
pictureBox1.Image = Image.FromFile(this.imageList[index]);
label1.Text = "Displaying image " + index + " of " + (this.imageList.Count - 1);
}
else
{
pictureBox1.Image = Image.FromFile(wbss.imageList[index]);
label1.Text = "Displaying image " + index + " of " + (wbss.imageList.Count - 1);
}
}
}
}
In form1 i have two options situations could be done.
Once if i'm using in the new form the way that i'm waiting for the backgroundworker to complete and then to wait untill it will navigate to all links in the List newHtmls and then after all images saved on hard disk for example 2453 images then i browse them in form1 pictureBox and hScrollBar.
Or the second option i'm using now that once an image saved to the hard disk in the new form then i will show the image in the form1 pictureBox1.
Then another image saved so now there are two images on hard disk so now show the last saved image. And so on once image saved display it on form1 pictureBox.
Just to show it. So i will see every X seconds images changing in form1 pictureBox.
The problem i'm facing now is in Form1 in this part:
if (wbss.htmlloaded == true)
{
var directory = new DirectoryInfo(#"e:\webbrowserimages\");
myFile = directory.GetFiles("*.bmp");
if (myFile.Length > 0)
{
var myFiles = (from f in directory.GetFiles("*.bmp")
orderby f.LastWriteTime descending
select f).First();
hScrollBar1.Enabled = true;
hScrollBar1.Minimum = 0;
hScrollBar1.Value = 0;
hScrollBar1.Maximum = 1;
hScrollBar1.SmallChange = 1;
hScrollBar1.LargeChange = 1;
pictureBox1.Image = Image.FromFile(myFiles.Name);
}
}
On the line:
pictureBox1.Image = Image.FromFile(myFiles.Name);
FileNotFoundException: Image3.bmp
But on my hard disk i see Image3.bmp
I will try to narrow cut some code but it's all connected the new form with form1.
You need to use myFiles.FullName. myFiles.Name only has the path relative to the directory the file is in, which is not enough to find the file. FullName includes the directory, so it's the full absolute path to the file.
And for gasake, name your controls. Form1 isn't a good name. pictureBox1 isn't a good name. Even the variable names are misleading - myFile for a collection of files, and then myFiles for a single file? And why are you calling GetFiles again when you already have a list in myFile? And why even check for file length? Why not just do directory.GetFiles("*.bmp").OrderByDescending(i => i.LastWriteTime).Select(i => i.FullName).FirstOrDefault()?

Horrible Flickering drawing in C#

Anyone have any suggestions on how to stop this drawing from flickering? I have tried each double buffering solution, stopped using .CreateGraphics, moved all of my functions all over the place, nothing has worked.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace Math
{
public partial class Form1 : Form
{
static Random rand = new Random();
ProblemBox[] problems = new ProblemBox[20];
#region Types
public enum Type
{
Basic, Algebric, Triginomic
}
public class Problem
{
public Type type;
public String problem, answer;
public Boolean isTrue;
public Problem(Type type, String problem, String answer, Boolean isTrue)
{
this.type = type;
this.problem = problem;
this.answer = answer;
this.isTrue = isTrue;
}
}
class ProblemBox
{
public Rectangle rect;
public Problem problem;
public ProblemBox(Problem problem)
{
rect = new Rectangle(0, 309, 244, 30);
this.problem = problem;
}
public void move()
{
rect.Y -= 1;
}
public void draw(Graphics g)
{
g.FillRectangle(Brushes.DarkGray, rect);
g.DrawString(problem.problem + "=" + problem.answer, new Font("Times New Roman", 12.0f), Brushes.DarkBlue, new PointF(rect.X + 5, rect.Y + 5));
}
}
#endregion
public Problem CreateProblem() {
char op = '+';
int a = rand.Next(20), b = rand.Next(20), c;
switch (rand.Next(4)) {
case 2:
c = a - b;
op = '-';
break;
case 3:
c = a * b;
op = '*';
break;
case 4:
c = a / b;
op = '/';
break;
default:
c = a + b;
op = '+';
break;
}
bool isTrue = rand.Next(2) == 1;
if (!isTrue) {
c += 1 + (10 - rand.Next(20));
}
return new Problem(Type.Basic, String.Concat(a + ""+op +""+ b), String.Concat(c), isTrue);
}
public Form1()
{
InitializeComponent();
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
problems[0] = new ProblemBox(CreateProblem());
}
private void panel1_Paint(object sender, PaintEventArgs e)//Tick
{
ProblemBox temp = null;
if (problems[0].rect.Y < 279)
{
temp = new ProblemBox(CreateProblem());
}
for (int i = 0; i < 20; i++)
{
if (temp != null)
{
ProblemBox temp2 = problems[i];
problems[i] = temp;
temp = temp2;
}
if (problems[i] != null)
{
problems[i].move();
problems[i].draw(e.Graphics);
}
}
Thread.Sleep(20);
DrawingPanel.Invalidate();
}
}
}
It's not a good idea to have
Thread.Sleep(20);
DrawingPanel.Invalidate();
inside Paint method. Try to avoid them and behavior may dramatically improved.
As Tigran already said, you problem is what you do not finishing repaint, which could be easily solve with something like:
(new Thread(() =>
{
Thread.Sleep(20);
this.BeginInvoke((MethodInvoker)delegate { DrawingPanel.Invalidate(); });
})).Start();
However, flickering can also occurs due to slow repainting (or rather say - not fast enough). Solution in that case if pretty simple - do not draw onto screen directly (use doublebuffering).
If you need some functionality from standard component, then you must create your own component and call it appropriately. Using Panel for something what has nothing to do for what Panel is intended for - is bad.
Here is a good starter:
[System.ComponentModel.DesignerCategory("Code")]
public class MyControl : PictureBox
{
public MyControl()
{
SetStyle(ControlStyles.UserPaint | ControlStyles.ResizeRedraw | ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
// ...
}
}

Why aren't the buttons in my C# Application working?

I am doing this lab out of a book on my own, and I made an application in which sharks are racing. There is a radio button that should update a label on the right dynamically, as well as a button that actually starts the race. Everything used to work and then I renamed a few things, and now nothing works.
Screenshot of application:
image http://cl.ly/f08f4e22761464e0c2f3/content
Form Class:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace project1
{
public partial class Game : Form
{
private Shark[] sharks;
private Guy[] guys;
private Guy selectedGuy;
public Game()
{
InitializeComponent();
Random moreRandom = new Random();
int start = myTrack.Location.X;
int finish = myTrack.Width - 65;
sharks = new Shark[4]
{
new Shark() {myRandom = moreRandom, myPictureBox = myShark1, myPBStart = start, trackLength = finish},
new Shark() {myRandom = moreRandom, myPictureBox = myShark2, myPBStart = start, trackLength = finish},
new Shark() {myRandom = moreRandom, myPictureBox = myShark3, myPBStart = start, trackLength = finish},
new Shark() {myRandom = moreRandom, myPictureBox = myShark4, myPBStart = start, trackLength = finish}
};
guys = new Guy[3]
{
new Guy() {myName="Joe", cash=50, myRadioButton=rbGuy1, myLabel=labelBet1},
new Guy() {myName="Bob", cash=75, myRadioButton=rbGuy2, myLabel=labelBet2},
new Guy() {myName="Al", cash=45, myRadioButton=rbGuy3, myLabel=labelBet3}
};
selectedGuy = guys[0];
rbGuy1.Tag = guys[0];
rbGuy2.Tag = guys[1];
rbGuy3.Tag = guys[2];
updateGui();
}
private void myChanged(object sender, EventArgs e)
{
selectedGuy = getSelectedGuy(sender);
betterLabel.Text = selectedGuy.myName;
}
private void betAmountValue(object sender, EventArgs e)
{
updateMin();
}
private void Bet_Click(object sender, EventArgs e)
{
int bet = (int) betAmount.Value;
int myFish = (int) sharkNumber.Value;
selectedGuy.placeBet(bet, myFish);
updateGui();
}
private void raceBtn_Click(object sender, EventArgs e)
{
betBtn.Enabled = false;
bool noWinner = true;
while(noWinner)
{
for (int dogFish = 0; dogFish < sharks.Length; dogFish++)
{
Application.DoEvents();
if(sharks[dogFish].Swim())
{
showWinner(dogFish);
collectBets(dogFish);
noWinner = false;
}
}
}
updateGui();
betBtn.Enabled = true;
}
private void showWinner(int fish)
{
MessageBox.Show(string.Format("Winner Winner People Dinner! \nShark {0} won!", fish + 1));
}
private void collectBets(int fish)
{
for (int guyNumber = 0; guyNumber < guys.Length; guyNumber++)
{
guys[guyNumber].collect(fish + 1);
guys[guyNumber].resetBet();
}
}
private void updateMin()
{
minBetLabel.Text = string.Format("Minimum bet: 5 bucks", betAmount.Value);
}
private Guy getSelectedGuy(object sender)
{
RadioButton rb = (RadioButton)sender;
return (Guy)rb.Tag;
}
private void updateGui()
{
for (int guyNumber = 0; guyNumber < guys.Length; guyNumber++)
{
guys[guyNumber].updateLabels();
}
for (int fish = 0; fish < sharks.Length; fish++)
{
sharks[fish].startPosition();
}
updateMin();
}
}
}
Shark Class:
using System;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
namespace project1
{
public class Shark
{
public int myPBStart; // Where the PictureBox starts
public int trackLength; // How long the racetrack is
public PictureBox myPictureBox = null; // The PictureBox object
public int location = 0; // My location on the racetrack
public Random myRandom; // An instance of Random
public Shark()
{
location = 0;
myPictureBox = new PictureBox();
myRandom = new Random();
trackLength = 100;
myPBStart = 0;
}
public bool Swim()
{
int distance = myRandom.Next(1, 4);
location += distance;
movePB(distance);
return location > trackLength;
}
private void movePB(int distance)
{
Point p = myPictureBox.Location;
p.X += distance;
myPictureBox.Location = p;
}
public void startPosition()
{
location = myPBStart;
Point p = myPictureBox.Location;
p.X = location;
myPictureBox.Location = p;
}
}
}
I can supply more resources if needed, but this is the main gist of it.
Using Visual Studio, make sure of the following:
1) For each radio button, verify the CheckedChanged event is hooked up to your myChanged function.
2) Verify the "Bets" Button.Click event is hooked up to your Bet_Click function.
3) Verify the "Race!" Button.Click event is hooked up to your raceBtn_Click function.
A safe way to rename things is to right click on the variable name, Refactor, Rename. This will ensure any references to the variable are renamed properly
when you renamed them you probably did it by editing the code rather than by changing the control properties.
THe Winforms designer in VS created code for you behind the scenes that wires the invents up. This codes uses the control names. Look for a file called formname_designer.cs. Notice that there are lines that still have the old control names. You can change this code
This is why its a good habit to give controls nice names when you start.
Make sure that the events on your controls are still connected to the correct event handlers in your code. Sometimes when you rename things, this link can get broken.

Categories