increase pen width with trackbar value - c#

As the it's said in the title, i am trying to increase pen width size by using a trackbar.
This is what i have written so far:
public partial class Form26_10 : Form
{
float scrollValue = 0F;
Pen CustomPen = new Pen(Color.Black, scrollValue);//ERROR<-
public Form26_10()
{
InitializeComponent();
}
private void trackBar1_Scroll(object sender, EventArgs e)
{
scrollValue = trackBar1.Value;
}
}
essentially i should be able to declare a value in memory, then have it in the pen width parameter and so when the trackbar value change's the pen width changes. Though i am getting this error:
a field initializer cannot reference the non-static field, method or property of 'Form.scrollValue'

public partial class Form26_10 : Form
{
private Pen CustomPen;
public Form26_10()
{
InitializeComponent();
CustomPen = new Pen(Color.Black, scrollValue);
}
private void trackBar1_Scroll(object sender, EventArgs e)
{
CustomPen.Width = trackBar1.Value;
}
}
You shouldn't initialize class fields at declaration if you've got a changing value. Also, float has a default value of 0.0F so you don't need to initialize it. I removed it in this example because I assumed you wouldn't need it. If you still plan on using it, you can just add it at the top.
float scrollValue;

Related

An object reference is required for the nonstatic field, method, or property 'member'. error in C#

Question:
Create a base class that contains the protected variable - rectangle
At the base. Create a successor class to the rectangle that
additionally Contains: private variables - height and area of ​​a
rectangle; Open A method that calculates and returns the area of ​​a
rectangle. Home In the program, create an object with an inherited
class type and call it Method.
So problem is shown on the picture, and i have no idea, what's wrong , or what the problem is.
This is the error:
namespace _4_2_Rectangle_
{
class Base
{
protected double fudze;
public Base(double fudze)
{
this.fudze = fudze;
}
}
class Rectangle : Base
{
private double height;
private double Area;
public Rectangle(double height): base(fudze)
{
this.height = height;
}
public double area()
{
Area = height * fudze;
return Area;
}
}
}
namespace _4_2_Rectangle_
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
double fudze, height, Area;
fudze = double.Parse(textBox1.Text);
height = double.Parse(textBox2.Text);
Base obj_2 = new Base(fudze);
Rectangle obj_1 = new Rectangle(height);
Area = obj_1.area();
label4.Text = Area.ToString();
}
}
}
This one is second class.
The problem is that "fudze" is not defined. You are creating the Rectangle at this moment and trying to pass a parameter to base class, been the parameter a field of this base class
public Rectangle(double height): base(fudze)
{
this.height = height;
}
Try with:
public Rectangle(double fudze, double height): base(fudze)
{
this.height = height;
}
It seems, that you should have two paramters in Rectangle;s constructor:
public Rectangle(double fudze, double height): base(fudze)
{
this.height = height;
//DONE: you can compute Area in the constructor as well:
Area = height * fudze;
}
Then when creating Rectangle instance you should provide two parameters:
private void button1_Click(object sender, EventArgs e)
{
double fudze, height, Area;
fudze = double.Parse(textBox1.Text);
height = double.Parse(textBox2.Text);
//DONE: Rectangle wants both fudze and height
Rectangle obj_1 = new Rectangle(fudze, height);
Area = obj_1.area();
label4.Text = Area.ToString();
}

How to prevent flickering in WinForms when quickly updating a value?

I have a simple Winforms GUI which has a TrackBar in a GroupBox its title I'm using to display the value of the contained TrackBar:
private void trackBar1_Scroll(object sender, EventArgs e)
{
UpdateTrackBarPositionText();
}
private void Form1_Load(object sender, EventArgs e)
{
UpdateTrackBarPositionText();
}
private void UpdateTrackBarPositionText()
{
groupBox1.Text = ORIGINAL_TRACKBAR_TEXT + qualitySelector.Value.ToString();
}
The problem is that when scrubbing over the bar, both it and the label of the group are flickering, especially when scrubbing quickly. Also CPU usage is fairly high for such a simple action. How can I improve this implementation? I want to update the value in real time, not just after letting go, so that the users sees the value while selecting it. DoubleBuffered = true; does nothing.
EDIT:
I used reflection at instantiation to set the GroupBox and the bar to double buffered. That helped with the Box, but the slider still flickers :(
Do you have Double Buffering set. If not start there and then other methods as needed.
This is a classical use case for a timer. Make it update the label at, say, 10 times per second. Any more than that is really an overkill because nobody can read it that fast anyway.
You can have the timer permanently enabled, or (as an optimization) you can enable it at trackBar1_Scroll and disable it in the timer itself, if the value hasn't changed for the past few ticks. In fact, if the value hasn't changed since the last update, don't update the label either (might save some extra flickering).
This does not address this question, but it creates a workaround with a custom control that does the same thing.
public partial class SliderControl : Control
{
public event EventHandler ValueChanged;
public int MinValue { get; set; }
public int MaxValue { get; set; }
public int Value { get; set; }
public SliderControl()
{
InitializeComponent();
SetStyle(ControlStyles.AllPaintingInWmPaint|ControlStyles.OptimizedDoubleBuffer, true);
this.MinValue=0;
this.MaxValue=100;
this.Value=50;
this.Text="Value";
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
SetBoundsCore(Left, Top, Width, 32, BoundsSpecified.Height);
}
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
pe.Graphics.DrawRectangle(Pens.Black, 0, 0, Width-1, Height-16);
using (var gp = new GraphicsPath())
{
var rect = new Rectangle(0, 0, Value*(Width-1)/MaxValue-1, Height-16);
gp.AddRectangle(rect);
using (var br = new LinearGradientBrush(rect, Color.SteelBlue, Color.LightBlue, LinearGradientMode.Horizontal))
{
pe.Graphics.FillPath(br, gp);
pe.Graphics.DrawPath(Pens.DarkBlue, gp);
}
}
var text = $"{this.Text} = {this.Value}";
var sz = pe.Graphics.MeasureString(text, SystemFonts.SmallCaptionFont);
pe.Graphics.DrawString(text, SystemFonts.SmallCaptionFont, Brushes.Black, Width/2-sz.Width/2, Height-16);
}
private void SetClickValue(Point click_point)
{
int x = (click_point.X+1)*MaxValue/Width;
this.Value=x;
this.Refresh();
this.ValueChanged?.Invoke(this, new EventArgs());
}
protected override void OnMouseClick(MouseEventArgs e)
{
base.OnMouseClick(e);
if (e.Button==MouseButtons.Left)
{
SetClickValue(e.Location);
}
}
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if (e.Button==MouseButtons.Left)
{
SetClickValue(e.Location);
}
}
}

DrawRectangle doesn't work

I have a rectangle on a class created by me. The function "DrawRectangle" doesn't draw anything. I put the code below:
My own class (Unidad.cs):
class Unidad
{
//Constructor
public Unidad(string tipo, int movimiento)
{
tipoUnidad = tipo;
movimientoUnidad = movimiento;
}
//Propiedades
public string tipoUnidad {get; set;}
public int movimientoUnidad { get; set; }
//Método para dibujar unidad
public void colocar(MouseEventArgs e)
{
Form1 myf = new Form1();
using (Graphics g = myf.picboxFondo.CreateGraphics())
{
Pen pen = new Pen(Color.Red, 2);
g.DrawRectangle(pen, e.X, e.Y, 20, 20);
pen.Dispose();
g.Dispose();
}
}
}
Main class:
public partial class Form1 : Form
{
//Prueba de clase
Unidad prueba;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
picboxFondo.Size = ClientRectangle.Size;
prueba = new Unidad("I", 20);
}
private void picboxFondo_MouseDown(object sender, MouseEventArgs e)
{
prueba.colocar(e);
}
}
I have picboxFondo Modifiers public. All compile correctly and works perfect, but when I go to g.DrawRectangle I see all the values are OK but it doesn't draw anything.
Can you help me?
Thanks!
You are creating a new instance of your Form1 class and try to draw on the PictureBox of that new instance (which isn't shown at all).
Instead you can pass the control you want to draw on as a parameter to your colocar method:
public void colocar(Point p, Control control)
{
using (Graphics g = control.CreateGraphics())
{
using (Pen pen = new Pen(Color.Red, 2))
{
g.DrawRectangle(pen, p.X, p.Y, 20, 20);
}
}
}
and call it like that in your form:
private void picboxFondo_MouseDown(object sender, MouseEventArgs e)
{
prueba.colocar(e.Location, picboxFondo);
}
I also changed the method so that you only pass the Location of the MouseEventArgs, because your drawing method doesn't need to know anything about mouse events, only about the Point.
And note that there is no need to call Dispose on the Pen or the Graphics, the using statement is doing that for you.
And you may consider using the .NET naming conventions and rename your method Colocar.

c# List.Add() unable to add correct values

Program suppose to draw shapes on panel1.
This is code for my main form:
namespace DrawShapes
{
public partial class Form1 : Form
{
List<Shape> myShapeList;
Shape shape;
public Form1()
{
InitializeComponent();
}
public void AddShape(Shape myshape)
{
myShapeList.Add(shape);
}
public List<Shape> MyShapeList
{
get { return myShapeList; }
}
private void Form1_Load(object sender, EventArgs e)
{
myShapeList = new List<Shape>();
shape = new Shape();
}
private void drawMeButton_Click(object sender, EventArgs e)
{
EditShape editShape = new EditShape();
editShape.Shape = shape;
if (editShape.ShowDialog() == DialogResult.OK)
{
this.shape = editShape.Shape;
myShapeList.Add(shape);
panel1.Invalidate();
}
editShape.Dispose();
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
int panelWidth = panel1.ClientRectangle.Width;
int panelHeight = panel1.ClientRectangle.Height;
Pen penLine = new Pen(Color.Blue, 1);
Graphics g = e.Graphics;
if (myShapeList != null)
{
foreach (Shape element in myShapeList)
{
label1.Text = element.Width.ToString();
g.DrawRectangle(penLine, element.XCordinates, element.XCordinates, 50, 50);
}
}
}
}
}
and here is code for my edit shape dialog box
namespace DrawShapes
{
public partial class EditShape : Form
{
Shape shape = null;
public EditShape()
{
InitializeComponent();
}
public Shape Shape
{
get { return shape; }
set { shape = value; }
}
private void button1_Click(object sender, EventArgs e)
{
shape.Width = 50;
shape.Height = 50;
shape.XCordinates = int.Parse(textBox1.Text);
shape.YCordinates = int.Parse(textBox2.Text);
shape.Type = 0;
DialogResult = DialogResult.OK;
}
}
}
I am having problem assigning shape object(from Edit Shape form) to myShapeList, all properties are set to 0 for some reason. Please help.
Perhaps the problem is your AddShape method. You seem to be adding shape each time instead of the shape that's getting passed into the method (myshape).
What happens if you do this instead?
public void AddShape(Shape myshape)
{
myShapeList.Add(myshape); // myshapeinstead of shape
}
It seems that you're not actually adding your shape to your shapelist. You're taking in myShape and then trying to add in shape. This should come up as an intellisense error.
public void AddShape(Shape myshape)
{
myShapeList.Add(shape);
}
EDIT: Nevermind, it wouldn't come up as an error because you have a member variable named shape. You're getting zero for everything because it's calling the default constructor for shape.
The big problem is in your call to the edit form. You are adding to the list the same object reference. So when you modify the reference inside the edit form you change all the elements added to the list to the inputs set in the latest call
Change your code to
private void drawMeButton_Click(object sender, EventArgs e)
{
using(EditShape editShape = new EditShape())
{
// Here, create a new instance of a Shape and edit it....
editShape.Shape = new Shape();
if (editShape.ShowDialog() == DialogResult.OK)
{
// Add the new instance to the list, not the same instance
// declared globally. (and, at this point, useless)
myShapeList.Add(editShape.Shape);
panel1.Invalidate();
}
// The using blocks makes this call superflous
// editShape.Dispose();
}
}
Then it is not clear when you call the method AddShape(Shape myshape) but it is clear that you have typo in that method
I have found my mistake.I Created new event handler with wrong parameters. Therefore information that suppose to be passed by my dialog OK button was never correctly assigned. Silly mistake. Thanks guys.

I have a context problem with c#

I have a problem with 2 Windows Forms which I created in c#. The first form (menu) has a PrintPreviewDialog object. The "menu" form then instantiates a copy of the send class "file" and call a ShopDialog method.
The "file" class write a file and calls a method (direct) in the "menu" class.
The problem I have is that the "direct" method is not known to the "menu" class. I think the answer is to define a copy of "menu" class in the "file", but I can't see have to do that.
Thanks for any help in advance.
John
namespace CSharp
{
public partial class MainMenu : Form
{
// Fields for printing.
public PrintDocument printDocument1 = new PrintDocument();
PageSettings printPageSettings = new PageSettings();
static RichTextBox printRichTextBox = new RichTextBox();
static string stringToPrint = "";
Font printFont = new Font("Arial", 10);
/****************************************************
* Select the Data->File-IO menu item. *
****************************************************/
private void fileIoToolStripMenuItem1_Click(object sender, EventArgs e)
{
File_IO fileIoDialog = new File_IO();
fileIoDialog.ShowDialog();
}
/****************************************************
* Initiate the printing process. The data to be *
* printed will be read from a file and stored in a*
* rich text box. The print menu buttons are *
* enabled. *
****************************************************/
public static void PrintInitialise(String printSource)
{
try
{
// Read text file and load into printRichTextBox.
FileStream printStream = new FileStream(printSource, FileMode.Open, FileAccess.Read);
printRichTextBox.LoadFile(printSource, RichTextBoxStreamType.PlainText);
printStream.Close();
// Initialise string to print.
stringToPrint = printRichTextBox.Text;
}
catch (Exception ex)
{
// Display error message if they appear.
MessageBox.Show(ex.Message);
}
}
/****************************************************
* Select the Data->File-IO menu item. *
****************************************************/
public void PrintDirect()
{
printDocument1.Print();
}
/****************************************************
* Select the Data->File-IO menu item. *
****************************************************/
private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
int numChars;
int numLines;
string stringForPage;
StringFormat strFormat = new StringFormat();
// Based on page setup, define drawable rectangle on page
}
}
}
namespace `enter code here`CSharp
{
public partial class File_IO : Form
{
MainMenu mainBransom;
public File_IO()
{
InitializeComponent();
}
private void btnPrint_Click(object sender, EventArgs e)
{
MainMenu.PrintInitialise(printSource);
mainBransom.PrintDirect();
}
You could use a property to store a reference to the menu class in the send class.
public class send: Form
{
public send(Form menuForm)
{
menu = menuForm;
}
public Form menu { get; private set; }
//... some other methods and properties
public void SomeButton_Click(object sender, EventArgs e)
{
// you have access to the direct method (provided it is public)
menu.direct();
}
}
In order to instantiate the send class you need to pass a reference to the menu form.

Categories