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);
}
}
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;
///.......................
}
}
This is my parent form:
public partial class ParentControl: UserControl
{
public ParentControl()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
ChildForm child= new ChildForm ();
child.Dock = DockStyle.Fill;
TabPage tabNewChild= new TabPage("Child");
tabNewChild.Controls.Add(child);
tabDetails.TabPages.Add(tabNewChild);
tabDetails.SelectedIndex = tabDetails.TabPages.IndexOf(tabNewChild);
}
void CloseTab()
{
\\Close the selected tab
}
}
This is my child usercontrol:
public partial class ChildForm : UserControl
{
public ChildForm ()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
\\Call the CloseTab in parent user control.
}
}
What is the optimal and proper way of implementing this?
I have researched about delegates and eventargs but cant decide what to use.
I have lots of modules that will be implemented in this way thats why I want to know the proper way of doing it. THanks a lot.
You can access to the Parent property of the ChildForm then cast it to ParentControl and call the CloseTab method:
public partial class ChildForm : UserControl
{
private void button1_Click(object sender, EventArgs e)
{
(Parent as ParentControl)?.CloseTab(this);
}
}
You may add the tab instance as method argument to close the good tab.
public partial class ParentControl: UserControl
{
public void CloseTab(ChildForm sender)
{
// close sender
}
}
A good solution is to create an event on your user control that is triggered when a close is requested:
public partial class ChildForm : UserControl
{
public ChildForm ()
{
InitializeComponent();
}
public event EventHandler CloseTabRequested;
protected virtual void OnCloseTabRequested(EventArgs e)
{
CloseTabRequested?.Invoke(this, EventArgs.Empty);
}
private void button1_Click(object sender, EventArgs e)
{
OnCloseTabRequested(EventArgs.Empty);
}
}
You can handle the event in the parent form:
public partial class ParentControl: UserControl
{
public ParentControl()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
ChildForm child= new ChildForm ();
child.Dock = DockStyle.Fill;
child.CloseTabRequested += ChildForm_CloseTabRequested;
TabPage tabNewChild= new TabPage("Child");
tabNewChild.Controls.Add(child);
tabDetails.TabPages.Add(tabNewChild);
tabDetails.SelectedIndex = tabDetails.TabPages.IndexOf(tabNewChild);
}
void ChildForm_CloseTabRequested(object sender, EventArgs e)
{
CloseTab((ChildForm)sender);
}
void CloseTab(ChildForm requestingForm)
{
\\Close the selected tab
}
}
With this solution the user control is not bound to a specific parent form for maximum reusability. It also avoids a dependency of the child form on the parent form, which is good design.
Here is how it should work:
Window1: A button click opens a new window and hides the current window
(This page contains a few textboxes)
public void applyBtn_Click(object sender, EventArgs e)
{
...
DataDisplay dd = new DataDisplay();
dd.Visibility = Visibility.Visible;
...
}
New Window: A button click opens Window1 from the same state (all the checkboxes, and textbox should contain the values from the time it was closed)
private void settings_btn_Click(object sender, RoutedEventArgs e)
{
Filters filter = new Filters();
filter.Visibility = Visibility.Visible;
}
//As you can see I am calling a new instance instead of reopening the same hidden instance.
Instead of creating a new instance every time, I'd prefer to use the same instance every time. If any other not so complicated ways out there, feel free to shoot!
If I understand you correctly, I think it would be better to have a "MainWindow" managing the 2 changing windows You could have it handled on the 2 Windows events or by using delegates:
public partial class MainWindow : Window
{
static frmFilters filterWindowInstance = new frmFilters(OpenDataDisplay);
static frmDataDisplay dataWindowInstance = new frmDataDisplay(OpenFilters);
static void OpenFilters()
{
filterWindowInstance.Visibility = Visibility.Visible;
dataWindowInstance.Visibility = Visibility.Collapsed;
}
static void OpenDataDisplay()
{
filterWindowInstance.Visibility = Visibility.Collapsed;
dataWindowInstance.Visibility = Visibility.Visible;
}
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
OpenFilters();
Visibility = Visibility.Collapsed;
}
}
public partial class frmFilters : Window
{
Action CloseFilterOpenData;
public frmFilters(Action CloseFilterOpenDataToSet)
{
InitializeComponent();
CloseFilterOpenData = CloseFilterOpenDataToSet;
}
private void cmdHideThis_Click(object sender, RoutedEventArgs e)
{
CloseFilterOpenData();
}
}
public partial class frmDataDisplay : Window
{
Action CloseDataOpenFilter;
public frmDataDisplay(Action CloseDataOpenFilterToSet)
{
InitializeComponent();
CloseDataOpenFilter = CloseDataOpenFilterToSet;
}
private void cmdHideThis_Click(object sender, RoutedEventArgs e)
{
CloseDataOpenFilter();
}
}
I have two windows, windowA that has a button to open windowB, and windowB has a button to close itself and also return List value. I tried this code, but the value keep null. windowB has RadGridView control, i want to get the selectedItem from it and add it on a list.
public class WindowA : Window
{
...
private void button_Click(object sender, RoutedEventArgs e)
{
WindowB winB = new WindowB();
if (winB.ShowDialog() == false)
{
listClass lc = winB.SelectedItemButton;
...
}
}
}
public class WindowB : Window
{
...
public listClass SelectedItemButton
{
get { return selectedItem; }
set
{
selectedItem = ((listClass)AGridView.SelectedItem);
}
}
private void button_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
}
the results are a listClass, but has no value inside. Why? and how can i make selectedItem = ((listClass)AGridView.SelectedItem); this line works to another window?
An example for you:
public partial class MainWindow : Window
{
private void Button_Click(object sender, RoutedEventArgs e)
{
Window1 dlg = new Window1();
if(dlg.ShowDialog()??false)
{
MessageBox.Show(dlg.S);
}
}
}
// Dialog
public partial class Window1 : Window
{
public string S
{
get
{
return this.txt1.Text;
}
}
private void btnClose_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = true;
}
}
you should create your listClass variable in Window1 and while you are opening the Window2 you should pass this variable as a parameter. Here is my demo:
First window:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
TestClass testClass = new TestClass();
testClass.Test = "Initial";
Second second = new Second(testClass);
second.ShowDialog();
label.Content = testClass.Test; // It prints "Changed"
}
}
Second window:
public partial class Second : Window
{
TestClass testClass;
public Second(TestClass sent)
{
InitializeComponent();
testClass = sent;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
testClass.Test = "Changed"; // Change the value
}
}
My testClass (listClass):
public class TestClass
{
public string Test { get; set; }
}
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
}
}