I have the mainwindow. I call the Usercontrols in the mainwindow. I call Usercontrol1 in the mainwindow.loaded section. I would like to bring Usercontrol2 instead of Usercontrol1 by clicking on a button inside Usercontrol1.
My usercontrol caller class:
public class uc_call
{
public static void uc_add(Grid grd, UserControl uc)
{
if (grd.Children.Count > 0)
{
grd.Children.Clear();
grd.Children.Add(uc);
}
else
{
grd.Children.Add(uc);
}
}
}
My Mainwindow_Loaded(It works):
uc_call.uc_add(Content, new UserControl1());
Button Click function in UserControl1:
MainWindow mw = new MainWindow();
uc_call.uc_add(mw.Content, new Usercontrol2());
Do not create a new MainWindow. Instead, use the existing one:
var topLevelPanel = Application.Current.MainWindow.Content as Panel;
if (topLevelPanel != null)
{
topLevelPanel.Children.Clear();
topLevelPanel.Children.Add(new Usercontrol2());
}
Note that is doesn't hurt to call Children.Clear() even when the collection is empty.
In case you've added another Content property that holds the Grid where you want to replace the child elements:
var mainWindow = (MainWindow)Application.Current.MainWindow;
var grid = mainWindow.Content;
grid.Children.Clear();
grid.Children.Add(new Usercontrol2());
or with your static method:
var mw = (MainWindow)Application.Current.MainWindow;
uc_call.uc_add(mw.Content, new Usercontrol2());
Related
I have a WPF application and here is the application structure:
Views
MainWindow.xaml, ABC.xaml (all with .cs files)
ViewModels
MainWindowVM.cs, ABCVM.cs
I have a Button in MainWindow.xaml (bound to MainWindowVM.cs) that calls a function, SampleFunction() in MainWindowVM.cs when being clicked and the SampleFunction() then creates a new instance of ABC.xaml (bound to ABCVM.cs) and open a new window of ABC.xaml using Show() function.
How can I make sure that clicking the Button in MainWindow would not open another new window of ABC.xaml when the old window is still there, or not create another new instance of ABC.xaml?
MainWindow.xaml.cs
public partial class MainWindow : Window
{
/*...Some other codes...*/
private MainWindowVM _VM = new MainWindowVM();
public MainWindowVM MainWindowVM
{
get { return _VM; }
set { _VM= value; }
}
public MainWindow()
{
InitializeComponent();
this.DataContext = MainWindowVM;
}
private void SomeControl_MouseLeftButtonUp(object sender,MouseButtonEventArgs e)
{
MainWindowVM.SampleFunction();
}
}
MainWindowVM.cs
public class MainWindowVM
{
/*...Some other codes...*/
public void SampleFunction()
{
ABC abc= new ABC();
abc.Show();
}
}
ABC.xaml.cs
public partial class ABC: Window
{
/*...Some other codes...*/
private static ABCVM _abcVM= new ABCVM();
public ABCVM ABCVM { get { return _abcVM; } set { _abcVM = value; } }
public ABC()
{
InitializeComponent();
this.DataContext = ABCVM;
}
}
Use ShowDialog() instead of Show().
Then you have to close the ABC.xaml first, before you can make something on the MainWindow. So you can't open a second ABC.xaml Window.
You can write code to check whether a window type object exists or not.
for each(Window win in Application.Current.Windows)
{
string windowType = win.GetType().ToString();
if (!windowType.Equals(nameSpace + "." + ABC))
{
ABC abc= new ABC();
abc.Show();
}
}
I am trying to change the label and text of a label which is inside a UserControl from within a Parent Form method at runtime.
So within the method in parent Form I do the following to change the label properties which is inside a UserControl
public partial class Form : Form
{
public void Form_Method()
{
UserControl uc = new UserControl();
uc.UpdateLabel(true);
}
}
And the custom method inside my UserControl
public partial Class UserControl : UserControl
{
public void UpdateLabel(bool value)
{
if (value)
{
lbl.Text = "This";
lbl.Forecolor = Color.Green;
}
if (value == false)
{
lbl.Text = "That";
lbl.Forcolor = Color.Red;
}
}
}
However when I navigated to the UserControl the label properties have not changed as I was creating a new instance of the usercontrol on the fly which
technically disappears after the method ends.
So I tried creating a public property of the actual UserControl as follows
public partial class Form : Form
{
public UserControl _uc;
public void Form_Method()
{
UserControl uc2 = new UserControl();
uc2.UpdateLabel(true);
_uc = uc2;
}
}
However it has no effect whatsoever? I have come across info of using Events or Delegates am not sure if they are the correct process for what am trying to do?
i'm coding a c# application using WPF
i have a main Window which contain a Grid named " SelectionGrid ". this grid will contain Control User, my problem is that i want to modify ( add/delete) Control User in that grid from a USER CONTROL itself
for example:
SelectionGrid host the User Control " Menu" in this menu there a button, i want from this button to remove the Menu User Control and add another User Control in this SelectionGrid
main window code :
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
UserControl usc = new Menu();
SelectionGrid.Children.Add(usc);
}}
Menu User Control code :
public partial class Menu : UserControl
{
public Menu()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
// want to add Another User Control in SelectionGrid
}
Firstly,put your userControl in some container control like Grid.Then you can easily access and modify the grid from the usercontrol as follows:
var parent = (Grid)this.Parent;
///do what you want to do with parent
A bit of knowledge-sharing : The below code can be used to access the parent of controls like Page,UserControl :
public static T FindParent(DependencyObject child)
{
DependencyObject parentObject = VisualTreeHelper.GetParent(child);
if (parentObject == null)
return null;
T parent = parentObject as T;
if (parent != null)
return parent;
else
return FindParent<T>(parentObject);
}
private void test()
{
ControlTypeHere parent = FindParent<ControlTypeHere>(this);
Hope this helps :)
How can I call method in UC from MainWindow? In my app I use MainWindow + UserControls + TabControl (one user control = one tabitem, as firefox). I would call method in user control when I change tabitem. I'll explain this with an example.
UserControl code:
MainWindow mw;
public userControl(MainWindow main)
{
this.mw = main;
InitializeComponent();
LoadData();
}
public void LoadData()
{
using (var mod = new Data())
{
try
{
var query = (from c in mod.table
select c).ToList();
dataGrid.ItemsSource = null;
dataGrid.ItemsSource = query;
}
catch {}
}
}
MainWindow code:
public void RefreshUserControl(string userControlName)
{
switch (userControlName)
{//... others UC
// ....
case "userControl":
userControl ue = new userControl(this);
ue.LoadData();
break;
}
}
private void tabUC_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var item = sender as TabControl;
var selected = item.SelectedItem as TabItem;
if (selected != null)
{
RefreshUserControl(selected.Name.ToString());
}
}
Generally, example - When I change tabitem on "userControl" then refresh datagrid on this usercontrol. Please help
Although I would suggest you to change your approach to create UCs here so that there is no dependency on MainWindow in UC but if you want to continue with it for now,
you can have an Event in your Main window
Raise that event when tab selection is changed
listen to that event in UC as you have MainWindow reference
do whatever you want to do in the event handler in UC
I am trying to access parent window from user control.
userControl1 uc1 = new userControl1();
mainGrid.Children.Add(uc1);
through this code I load userControl1 to main grid.
But when I click on a button inside userControl1 then I want to load another userControl2 into mainGrid which is in main window?
Have you tried
Window yourParentWindow = Window.GetWindow(userControl1);
This gets the root level window:
Window parentWindow = Application.Current.MainWindow
or the immediate parent window
Window parentWindow = Window.GetWindow(this);
The only reason why the suggested
Window yourParentWindow = Window.GetWindow(userControl1);
didnt work for you is because you didn't cast it to the right type:
var win = Window.GetWindow(this) as MyCustomWindowType;
if (win != null) {
win.DoMyCustomWhatEver()
} else {
ReportError("Tough luck, this control works only in descendants of MyCustomWindowType");
}
Unless there has to be way more coupling between your type of windows and your control, I consider your approach bad design .
I'd suggest to pass the grid on which the control will operate as a constructor parameter, make it into a property or search for appropriate (root ?) grid inside any Window dynamically.
Modify the constructor of the UserControl to accept a parameter of MainWindow object. Then pass the MainWindow object to the UserControl when creating in the MainWindow.
MainWindow
public MainWindow(){
InitializeComponent();
userControl1 uc1 = new userControl1(this);
}
UserControl
MainWindow mw;
public userControl1(MainWindow recievedWindow){
mw = recievedWindow;
}
Example Event in the UserControl
private void Button_Click(object sender, RoutedEventArgs e)
{
mw.mainGrid.Children.Add(this);
}
Thanks for help me guys. i got another solution
((this.Parent) as Window).Content = new userControl2();
this is perfectly works
Make a static instance of main window ,you can simply call it in your user control:
See this example:
Window1.cs
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
_Window1 = this;
}
public static Window1 _Window1 = new Window1();
}
UserControl1.CS
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
private void AddControl()
{
Window1._Window1.MainGrid.Children.Add(usercontrol2)
}
}