• 0

[C#] Dynamic Event Handling


Question

I have an arbitrary list of elements that I'm adding to a tableLayoutPanel (it was the first layout I came across that I could add elements to and it would be scrollable). For each element, I add the name of the element, with a TrackBar and a TextBox. (so three controls per row).

I want to link the TrackBar with the TextBox in a way where when I move the TrackBar, it changes the numeric value in the textBox to the value of the TrackBar (and ViceVersa).

I know how to add the Events for the two (+= new EventHandler(Scrolled)). The problem is all my elements are being added with the same EventName, so no matter which control I manipulate, i want the corresponding controls to change as well... I think this is OK, because I don't know how many of these elements I will have until runtime.

My question is this... inside the Scrolled method, how can I make elementScrollBar1 change elementTextBox1, and 2 -> 2, 3 -> 3, etc? The only things passed in are object sender, EventArgs events. Is what I'm trying to do possible? If so please help.

Link to comment
https://www.neowin.net/forum/topic/610910-c-dynamic-event-handling/
Share on other sites

21 answers to this question

Recommended Posts

  • 0

You need something like this:

		private void AddControls_Click(object sender, EventArgs e)
		{
			TextBox textbox = new TextBox();
			TrackBar trackbar = new TrackBar();
			trackbar.Maximum = 10;
			trackbar.Tag = textbox;

			trackbar.Scroll +=  delegate(object sender2, EventArgs e2)
								{
									TrackBar currentTrackBar = sender2 as TrackBar;
									TextBox currentTextBox = currentTrackBar.Tag as TextBox;
									currentTextBox.Text = currentTrackBar.Value.ToString();
								};
			tableLayoutPanel1.Controls.AddRange(new Control[] { textbox, trackbar });

		}

Add that into a button click event.

Hope this helps.

  • 0

My controls are added dynamically when the program is run, not by a click event... I'm guessing replacing my code with this for those two controls will have the same effect? Looking at this it seems like I should do this for other trackbar/textbox combos I have... this links the two I'm guessing?

Does this also allow someone to edit the textbox and it affect the trackbar?

  • 0

I figured out that it doesn't and modified my code to make it work.. I did something similar to what you showed, using the textBox.Tag = trackBar to put a reference.

Is this common practice? If I want to relate two controls, should I just reference each within the Tag variable? Is that common practice? It seems a little odd to me, even though it works as a hack.

  • 0

Why don't you create a custom control that includes the elements you need, and put the logic there? That's probably the most common practice in this case, since it's exactly why custom controls exist...

Just add a new UserControl to your project, name it something useful, and add a TextBox and Trackbar to it with the layout you want. Then set up the event handlers as you normally would inside the control, you can even use the Forms Designer for all of this.

Then in your main app, instead of dynamically generating TextBoxes and Trackbars, you add MyCustomControls that encapsulate the functionality you need. If you need to you can then expose a method or property on your custom control like GetValue() that returns the value (as indicated by both the textbox and trackbar).

  • 0

I didn't know about this custom control stuff, this seems to be much easier to work with... but I have a new problem because of it

So I have a control with a bunch of controls, one of them again linking a trackbar to a textBox... when I manipulate the trackBar, it updates the textBox correctly.. I have all the event stuff inside the Control Class... but the problem is, whenever I change the trackBar I want to call my update() method from the main class (Form1)... How would one do this?

Edited by zackiv31
  • 0
  zackiv31 said:
I didn't know about this custom control stuff, this seems to be much easier to work with... but I have a new problem because of it

So I have a control with a bunch of controls, one of them again linking a trackbar to a textBox... when I manipulate the trackBar, it updates the textBox correctly.. I have all the event stuff inside the Control Class... but the problem is, whenever I change the trackBar I want to call my update() method from the main class (Form1)... How would one do this?

Ideally, your control would expose an event that would notify any listeners that the trackbar has changed.

  • 0

You would create a delegate and an event that are public in your user control, and when you handle the trackbar change event in your user control, you fire another event indicating that it changed to the 'outside' world.

using System;
using System.ComponentModel;
using System.Windows.Forms;

namespace cs3
{
	public delegate void ValueChangedHandler(object sender, int newValue);

	public partial class UserControl1 : UserControl
	{
		public UserControl1()
		{
			InitializeComponent();
			textBox1.Text = trackBar1.Value.ToString();
		}

		[Category("Action")]
		public event ValueChangedHandler ValueChanged;

		private void trackBar1_ValueChanged(object sender, EventArgs e)
		{
			textBox1.Text = trackBar1.Value.ToString();
			OnValueChanged(trackBar1.Value);
		}

		protected void OnValueChanged(int newValue)
		{
			if (ValueChanged != null)
				ValueChanged(this, newValue);
		}
	}
}

  • 0
  zackiv31 said:
		[Category("Action")]
		  public event ValueChangedHandler ValueChanged;

This is new to me.. but seems interesting... what exactly are the [] for? What does it represent or tell he compiler?

It's an attribute for the designer. Add the control to your form, and then select the control. In the Properties pane of the designer, you see properties categorized. If you click on the Events button(the lightning bolt), it lists the events that your control exposes. If you didn't put the CategoryAttribute above your event, it would show up at the bottom of the list in the Misc category.

Attributes are one of the cool aspects of .NET that can be leveraged in many interesting ways. You could effectively describe your class with attributes and discover the metadata at runtime, and perform actions based on it. I've built a framework that utilized attributes to describe how properties should be validated. It was only a proof of concept, but it worked quite well. I'm now seeing that same idea show up in other frameworks, such as the Castle Project's MVC framework.

Edited by azcodemonkey
  • 0

here's my userControl:

	public delegate void ValueChangedHandler(object sender);

	public partial class ListBag : UserControl
	{
		[Category("Action")]
		public event ValueChangedHandler ValueChanged;

here's the declaration in Form1:

ListBag lb = new ListBag();
					lb.ValueChanged += new ValueChangedHandler;

It doesn't recognize this, it tries to make it " += ValueChangedHandler(someNameHere)"...

  • 0

But you said you wanted your Form1 to know when something changed inside the user control. That's why you need to have a method inside Form1 that gets called when the event is fired. It can be named anything you want (like OnListBagValueChanged or something).

  • 0
  zackiv31 said:
wo wo wo... OnValueChanged is a part of my custom UserControl... therefore Form1 has no idea abou the inner workings of it...

someone confirm this? (and help still)

Your form needs to have a method that matches the signature of the delegate of your control.

protected void UserCtrlValueChanged(object sender)
{
	...
}

Then you can use the += syntax to add a new handler in your form's InitializeComponent method.

userCtrlInstance.ValueChanged += new ValueChangedHandler(UserCtrlValueChanged);

You should be able to do this completely through the designer. Add the control to your form, select the control, go to the Properties panel in the IDE and select the Event(lightning bolt), and double-click the ValueChanged event in the UI. This will do all of the above correctly for you.

Edit: Brandon got it. :)

  • 0

Not that it matters much, but if that's what you delegate looks like - you don't actually need a custom one. Just use the built-in EventHandler delegate. Other than that little nit, it looks like you've got things figured out.

  • 0

Well it depends. Are you using:

public delegate void ValueChangedHandler(object sender);

or

public delegate void ValueChangedHandler(object sender, int newValue);

If the latter, then just keep it as is. If the former, then you don't need to declare that delegate at all.

protected void UserCtrlValueChanged(object sender)
{
...
}

in your main form, becomes

protected void UserCtrlValueChanged(object sender, EventArgs e)
{
...
}

And everywhere you used "ValueChangedHandler" before, you could now use just the built-in EventHandler delegate.

For example:

userCtrlInstance.ValueChanged += new ValueChangedHandler(UserCtrlValueChanged);

becomes

userCtrlInstance.ValueChanged += new EventHandler(UserCtrlValueChanged);

But if you are using a custom delegate to pass an integer with the new value, then you'll want to keep doing it the way you are. And when the event is raised, you just pass EventArgs.Empty for the second parameter.

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Posts

    • WYSIWYG Web Builder 20.2.1 by Razvan Serea Web Buialder is a WYSIWYG (What-You-See-Is-What-You-Get) program used to create complete web sites. WYSIWYG means that the finished page will display exactly the way it was designed. The program generates HTML (HyperText Markup Language) tags while you point and click on desired functions; you can create a web page without learning HTML. Just drag and drop objects to the page position them "anywhere" you want and when youre finished publish it to your web server (using the build in Publish tool). Web Builder gives you full control over the content and layout of your web pages. One Web Builder project file can hold multiple web pages. Desktop publishing for the web, build web sites as easy as Drag & Drop "One Click Publishing" No FTP program needed. No special hosting required, use with any Hosting Service! Easily create forms using the built-in Form Wizard plus Form validation tools and built-in CAPTCHA. Advanced graphics tools like shapes, textart, rotation, shadows and many other image effects. Fully integrated jQuery UI (Accordion, Tabs etc), animations, effects and built-in ThemeRoller theme editor. Google compatible sitemap generator / PayPal eCommerce Tools Many navigation tools available: Navigation bars, tab menus, dropdown menus, sitetree, slidemenus. Built-in Slide Shows, Photo Galleries, Rollover images, Banners etc. Support for YouTube, Flash Video, Windows Media Player and many other video formats. Unique extension (add-on) system with already more than 250 extensions available! Create HTML5 / CSS3 websites today HTML5 document type (optimized HTML5 output). HTML5 audio/video and YouTube HTML5 support. HTML5 forms: native form validation, new input types and options, web storage. HTML5 canvas and svg support in shapes and other drawing tools. CSS3 @font-face. Use non web safe fonts in all modern browsers. CSS3 opacity, border radius, box shadow. CSS3 gradients. Add cool gradient effects using native CSS3 (no images). CSS3 navigation menu. Create awesome menus without using JavaScript or images. CSS3 animations and transitions. Including support for 2D and 3D transforms! Features for advanced users: Login Tools/Page Password Protection. Built-in Content Management System with many plug-ins (guestbook, faq, downloads, photo album etc). Add custom HTML code with the HTML tools. JavaScript Events: Show/hide objects (with animation), timers, move objects, change styles etc. Layers: Sticky layer, Docking layer, Floating layer, Modal layer, Anchored layer, Strechable layer and more! jQuery Theme Manager, create your own themes for the built-in jQuery UI widgets. Style Manager (global styling, H1, H2, H3 etc). Master Frames and Master Objects: reuse common element in your website. and much more! WYSIWYG Web Builder 20.2.1 changelog: Improved: Images in the properties of Photo Gallery, Photo Grid, Photo Collage and Slide Show can now be re-arrange using drag & drop. Improved: Default aspect ratio of HTML5 audio Fixed: Issue with list item icon offset in workspace. Fixed: 'Edit' button text in Login Admin cannot be changed. Fixed: Issue with Card max-width size calculation in breakpoints Fixed: Issue with (fixed) Layout Grid column height in breakpoints. Download: WYSIWYG Web Builder 64-bit | 30.1 MB (Shareware) Download: WYSIWYG Web Builder 32-bit | 28.0 MB Screenshot: >> Click here << Link: Home Page | Templates | Free extras/addons | Changelog Get alerted to all of our Software updates on Twitter at @NeowinSoftware
    • Damn no doubt this is gonna be good, can't think of many franchises as consistent as RE (apart from 3 remake)
    • There are two version of qbittorrent 5.1.0 The normal version which I think is based of QT5 & the QT6 lt20 version. I'm currently using the QT6 LT20 version of 5.1.0 and it downloaded an ubuntu iso perfectly fine.
    • Are we forgetting the hardware degradation on 13th and 14th gen??
    • Cry more. The Ukrainians who had internet access because of Starlink were trash too, huh?
  • Recent Achievements

    • One Year In
      Vladimir Migunov earned a badge
      One Year In
    • One Month Later
      daelos earned a badge
      One Month Later
    • Week One Done
      daelos earned a badge
      Week One Done
    • Mentor
      Karlston went up a rank
      Mentor
    • One Month Later
      EdwardFranciscoVilla earned a badge
      One Month Later
  • Popular Contributors

    1. 1
      +primortal
      494
    2. 2
      snowy owl
      252
    3. 3
      +FloatingFatMan
      250
    4. 4
      ATLien_0
      225
    5. 5
      +Edouard
      181
  • Tell a friend

    Love Neowin? Tell a friend!