Is there a way to give a User Control custom events, and invoke the event on a event within the user control. (I'm not sure if invoke is the correct term)
public partial class Sample: UserControl
{
public Sample()
{
InitializeComponent();
}
private void TextBox_Validated(object sender, EventArgs e)
{
// invoke UserControl event here
}
}
And the MainForm:
public partial class MainForm : Form
{
private Sample sampleUserControl = new Sample();
public MainForm()
{
this.InitializeComponent();
sampleUserControl.Click += new EventHandler(this.CustomEvent_Handler);
}
private void CustomEvent_Handler(object sender, EventArgs e)
{
// do stuff
}
}
Aside from the example that Steve posted, there is also syntax available which can simply pass the event through. It is similar to creating a property:
class MyUserControl : UserControl
{
public event EventHandler TextBoxValidated
{
add { textBox1.Validated += value; }
remove { textBox1.Validated -= value; }
}
}
I believe what you want is something like this:
public partial class Sample: UserControl
{
public event EventHandler TextboxValidated;
public Sample()
{
InitializeComponent();
}
private void TextBox_Validated(object sender, EventArgs e)
{
// invoke UserControl event here
if (this.TextboxValidated != null) this.TextboxValidated(sender, e);
}
}
And then on your form:
public partial class MainForm : Form
{
private Sample sampleUserControl = new Sample();
public MainForm()
{
this.InitializeComponent();
sampleUserControl.TextboxValidated += new EventHandler(this.CustomEvent_Handler);
}
private void CustomEvent_Handler(object sender, EventArgs e)
{
// do stuff
}
}
Related
I'm developing a C# and WPF app.
I have a WPF Page 'HomeView' with a UserControl 'CreateItem'. After I click a Button (which related function is Close()) inside the UserControl, I have to make the UserControl visibility collapsed and call a function 'ReloadAnalytics' in the Page code.
namespace iMP
{
public partial class CreateItem : UserControl
{
public CreateItem()
{
InitializeComponent();
}
private void Close(object sender, RoutedEventArgs e)
{
HomeView objHomeView= new HomeView();
objHomeView.CreateNewItemDisplayGrid.Visibility = Visibility.Collapsed;
objHomeView.InitializeAnalyticsOverview();
}
}
When I call this function, pressing the Button, nothing happens. (CreateNewItemDisplayGrid is the name of the UserControl in HomeView)
(HomeView namespace is iMP.Views and the public partial class is HomeView : Page)
Follow the structure below. I defined an event in usercontrol and use that event in the main form.
Try to match the code with your code
In UserControl
public partial class CreateItem : UserControl
{
public event ClickEventHandler CloseButtonClick;
public delegate void ClickEventHandler(object Sender, RoutedEventArgs e);
public CreateItem()
{
InitializeComponent();
}
private void Close(object sender, RoutedEventArgs e)
{
if (CloseButtonClick != null)
{
CloseButtonClick(this, e);
}
}
}
In HomeView
public partial class HomeView : Page
{
public HomeView()
{
InitializeComponent();
CreateItem userControl = new CreateItem();
this.Content = userControl;
userControl.CloseButtonClick += UserControl_CloseButtonClick;
}
private void UserControl_CloseButtonClick(object Sender, RoutedEventArgs e)
{
///...................................
this.CreateNewItemDisplayGrid.Visibility = Visibility.Collapsed;
///.......................
}
}
Had a look on here and found several examples but they don't seem to fit my exact problem and through experimentation I can't work it out.
Current code for form...
public partial class Form1 : Form
{
DualCombo dc = new DualCombo();
public Form1()
{
InitializeComponent();
this.Controls.Add(dc);
}
private void MyMethod()
{
MessageBox.Show(dc.c1.Text + dc.c2.Text);
}
private void Form1_Load(object sender, EventArgs e)
{
}
}
The control that contains 2 of my custom combos...
public class DualCombo : UserControl
{
public CustomCombo c1 = new CustomCombo();
public CustomCombo c2 = new CustomCombo();
public DualCombo()
{
c1.Items.Add("One");
c1.Items.Add("Two");
c1.Items.Add("Three");
c2.Left = c1.Right;
c2.Items.Add("One");
c2.Items.Add("Two");
c2.Items.Add("Three");
this.Controls.Add(c1);
this.Controls.Add(c2);
}
}
I have left the code from the custom combo blank to keep the example simple...
public class CustomCombo : ComboBox
{
}
I would like my custom combo OnSelectedIndex changed to trigger the following method that is in the form...
private void MyMethod()
{
MessageBox.Show(dc.c1.Text + dc.c2.Text);
}
The easiest solution is to subscribe to that event directly:
public Form1()
{
InitializeComponent();
this.Controls.Add(dc);
dc.c1.SelectionChangedEvent += (s, e) => MyMethod();
}
But this is bad idea to make c1 public, read further.
UserControl is encapsulated control with some functionality. If you need to inform someone who is using that UserControl about something simple create an event:
Add event to UserControl
public EventHandler SomeEvent;
protected void OnSomeEvent() => SomeEvent?.Invoke(this, EventArgs.Empty);
Fire it when selection is changed from within UserControl
protected CustomCombo c1 = new CustomCombo();
public DualCombo()
{
c1.SelectedIndexChanged += (s, e) => OnSomeEvent();
...
}
Now you can subscribe to that event in your form (where this UserControl is used):
DualCombo dc = new DualCombo();
public Form1()
{
InitializeComponent();
this.Controls.Add(dc);
dc.SomeEvent += (s, e) => MyMethod(); // call your method
}
Tips: do not make controls inside UserControl public. Think about UserControl as a black box.
I've got a AddWindow to add new client, the MainWindow (which is always showed) and I want to send the information from Addwindow to ListBox in MainWindow (I mean i need to add new item to listbox).
Someone knows how can I do that?
You can do that with events of that object like this :
public partial class AddWindow : Window
{
public AddWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
if (Check != null)
Check(TextBox.Text);
}
public event Action<string> Check;
}
and in main window
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
AddWindow popup = new AddWindow();
popup.Check += popup_Check;
popup.Show();
}
void popup_Check(string obj)
{
ListBox.Items.Add(obj);
}
}
I want this:
public partial class ucTest : UserControl
{
...
SomeEvent { MessageBox.Show("Inner Call") }
}
public partial class frmTest: Form
{
...
SomeEvent += OuterEventInstance;
...
void OuterEventInstance(object sender, EventArgs e)
{ MessageBox.Show("Inner Call") }
...
}
How can I define a public event on a user control that is available (and expandable) in the form that contains an instance of this user control?
Something like this:
public partial class ucTest : UserControl
{
public event EventHandler SomeEvent;
private void OnSomeEvent()
{
EventHandler handler = SomeEvent;
if(handler != null)
handler(this, EventArgs.Empty);
}
}
public partial class frmTest: Form
{
public frmTest()
{
ucTest uc = new ucTest();
uc.SomeEvent += OuterEventInstance;
}
//...
void OuterEventInstance(object sender, EventArgs e)
{
MessageBox.Show("Inner Call")
//...
}
}
Any way to make this working code simpler ie the delegate { }?
public partial class Form1 : Form
{
private CodeDevice codeDevice;
public Form1()
{
InitializeComponent();
codeDevice = new CodeDevice();
//subscribe to CodeDevice.ConnectionSuccessEvent and call Form1.SetupDeviceForConnectionSuccessSate when it fires
codeDevice.ConnectionSuccessEvent += new EventHandler(SetupDeviceForConnectionSuccessState);
}
private void SetupDeviceForConnectionSuccessState(object sender, EventArgs args)
{
MessageBox.Show("It worked");
}
private void button1_Click(object sender, EventArgs e)
{
codeDevice.test();
}
}
public class CodeDevice
{
public event EventHandler ConnectionSuccessEvent = delegate { };
public void ConnectionSuccess()
{
ConnectionSuccessEvent(this, new EventArgs());
}
public void test()
{
System.Threading.Thread.Sleep(1000);
ConnectionSuccess();
}
}
WinForm event subscription to another class
How to subscribe to other class' events in c#?
If don't think you could simplyfy:
public event EventHandler ConnectionSuccessEvent = delegate { }
even in c#3 + you could only do
public event EventHandler ConnectionSuccessEvent = () => { }
However you could simplify
codeDevice.ConnectionSuccessEvent += new EventHandler(SetupDeviceForConnectionSuccessState);
to
codeDevice.ConnectionSuccessEvent += SetupDeviceForConnectionSuccessState;