I have 2 windows on my project. For example, on first window, I have a label. I want to change the text of this label from other window.
selectwindow win2 = new selectwindow();
win2.Show();
with this command we can open another window. but how can we change a property of an object from another window?
Your classes that inherit from Window can have their own properties and functions. Simply create a public function on your second Window class
public class SecondWindow:Window{
public void UpdateSomething(string text) {
//your code here
}
}
You can then call it in the first window with
var mywindow = new SecondWindow()
mywindow.Show()
mywindow.UpdateSomething("your text")
But you should read more on C# to begin with because this is quite basic and you shouldn't call functions in such a way because it produces spaghetti code. You should read more about WPF and MVVM
Related
So I'm still learning how to do C# applications and I have actually a problem with a window.
I've created a WPF project and I've separated some part of my main window in sub-parts (user-controls) so I can have a cleaner xaml code to work with.
I have a lot of different UserControl such as UserControlMenuStrip. All of them are inside the MainWindow.
Inside the MenuStrip was a MenuItem called Parameters :
<MenuItem Header="_Parameters" x:Name="MenuParameters"/>
I have created a new window called ParametersWindow. My goal was to open a child window centered with the main window when I click on the item.
But I don't really know how to proceed? Should I make a click= event and write down the code inside the linked UserControlMenuItem.xaml.cs linked file? Or in the MainWindow.xaml.cs file? Or maybe a new and clean file?
When I try to put it inside UserControlMenuItem.xaml.cs, I can't properly set the owner of the window I create this method but I can't set the owner:
private void OpenParametersWindow()
{
WindowParameters WinParam = new WindowParameters();
WinParam.Owner = MainWindow();
WinParam.WindowStartupLocation = WindowStartupLocation.CenterOwner;
WinParam.Show();
}
And, when I try via the MainWindow.xaml.cs I can't even get the variable...
So... How can I properly open the Window properly? And should I do it in the xaml.cs file or create a new one for a better understanding?
I've Created a class and added a static field as MainWindow to holding reference
class ReferenceClass
{
public static MainWindow mainWindow = null;//firstly null.we will set it in WindowLoaded event.
}
You can create a class like this for accessing reference of your MainWindow from wherever you want.Give your MainWindow reference to its static field.
MainWindow Loaded Event
private void Window_Loaded(object sender, RoutedEventArgs e)
{
ReferenceClass.mainWindow = this; //setting the reference to static field of ReferenceClass.
}
Menu Click (Event called on MenuStrip UserControl)
private void MenuItem_Click(object sender, RoutedEventArgs e)
{
NewWindow nw = new NewWindow();
nw.Owner = ReferenceClass.mainWindow;//Calling the reference of MainWindow from our class.
nw.WindowStartupLocation = WindowStartupLocation.CenterOwner;
nw.Show();
}
Here we go
Project
This is just a way for solving this issue.We can find more solutions which are better than mine but i use this solution when i need.
A handle to the parent window for any usercontrol can be obtained that way:
Window wndParent = System.Windows.Window.GetWindow(this);
WinParam.Show(wndParent);
But when working with WPF, it is more convenient to use the MVVM pattern
As you writing UI in WPF it is preferred to implement it with MVVM pattern. It allows you to have a clear separation of concerns between code and presentation.
Regarding your question about how to set Owner I suggest reading this series of articles about dialogs in WPF implemented with MVVM in mind
https://www.c-sharpcorner.com/article/dialogs-in-wpf-mvvm/
I currently have one window designed in WPF and coded in C#. I want one of my buttons to open another window, which I would also like to design in WPF. What is the best way for me to do this? Can I make multiple xaml files and call them from the same .cs class? Or should I just have one xaml file? I tried to add a new window into my xaml but it won't allow me to do that. I want all the code to be in the same C# class.
Yes, you can have multiple XAML files and call them from the same .cs file.
For exemple, let's say you have Window1.xaml and Window2.xaml. Window1 is your main window, and the code behind will look like this :
public partial class Window1 : Window
{
public MainWindow()
{
InitializeComponent();
}
}
In Window1 you have a button named btnOpenWindow. On click, you may do that to open Window2 :
private void btnOpenWindow_Click(object sender, RoutedEventArgs e)
{
var window = new Window2();
window.Show();
}
Then a new Window2 is opened.
However you won't be able to get events or others things coming from Window2 in Window1.xaml.cs, obviously you will control that in Window2.xaml.cs for exemple.
You should use the MVVM pattern in your project.
So you have different windows and just one ViewModel to handel these views and your data.
Have a look on: MVVM: Tutorial from start to finish?
I want to call a method from user control in WPF
I´ve a Window with a list and I have a method that get this list.
private ObservableCollection<int> _lst;
public MainWindow()
{
InitializeComponent();
getList();
}
public void getList()
{
_lst = List<int>();
}
In this page I use a usercontrol:
UserControlAAA userControl = new UserControlAAA ();
gridDatos.Children.Add(userControl);
I want to do something like this inside of usercontrol:
Window win = Window.GetWindow(this);
win.getList();
but I can´t call win.getList();
I want to call the method getList from my usercontrol, but I don´t know how to do it.
You'll need to cast the Window object to the specific window type you're using - which in your case is MainWindow:
MainWindow win = (MainWindow)Window.GetWindow(this);
win.getList();
However, it's not wise to have such coupling between the user control and the window it's hosted in, since that means you will only be able to use it in a window of type MainWindow. It would be better to expose a dependency property in the user control and bind the list to that property - this way the user control will have the data it requires and it will also be reusable in any type of window.
Solution from #Adi Lester is working but it break WPF coding ruler. Proper way of doing this is using event like in the linked answer below
https://stackoverflow.com/a/19384953/3099317
I want to access my controls like button or textbox in mainWindow in WPF, but I can't do this.
In Windows Form application it's so easy, you can set modifier of that control to True and you can reach that control from an instance of that mainWindow, but in WPF I can't declare a public control. How can I do this?
To access controls in another WPF forms, you have to declare that control as public. The default declaration for controls in WPF is public, but you can specify it with this code:
<TextBox x:Name="textBox1" x:FieldModifier="public" />
And after that you can search in all active windows in the application to find windows that have control like this:
foreach (Window window in Application.Current.Windows)
{
if (window.GetType() == typeof(Window1))
{
(window as Window1).textBox1.Text = "I changed it from another window";
}
}
Unfortunately, the basics of WPF are data bindings. Doing it any other way is 'going against the grain', is bad practice, and is generally orders of magnitude more complex to code and to understand.
To your issue at hand, if you have data to share between views (and even if it's only one view), create a view model class which contains properties to represent the data, and bind to the properties from your view(s).
In your code, only manage your view model class, and don't touch the actual view with its visual controls and visual composition.
I found that in WPF, you have to cast Window as a MainWindow.
Looks complicated but it's very easy! However, maybe not best practices.
Supposing we have a Label1, a Button1 in the MainWindow, and you have a class that deals with anything related to the User Interface called UI.
We can have the following:
MainWindow Class:
namespace WpfApplication1
{
public partial class MainWindow : Window
{
UI ui = null;
//Here, "null" prevents an automatic instantiation of the class,
//which may raise a Stack Overflow Exception or not.
//If you're creating controls such as TextBoxes, Labels, Buttons...
public MainWindow()
{
InitializeComponent(); //This starts all controls created with the XAML Designer.
ui = new UI(); //Now we can safely create an instantiation of our UI class.
ui.Start();
}
}
}
UI Class:
namespace WpfApplication1
{
public class UI
{
MainWindow Form = Application.Current.Windows[0] as MainWindow;
//Bear in mind the array! Ensure it's the correct Window you're trying to catch.
public void Start()
{
Form.Label1.Content = "Yay! You made it!";
Form.Top = 0;
Form.Button1.Width = 50;
//Et voilá! You have now access to the MainWindow and all it's controls
//from a separate class/file!
CreateLabel(text, count); //Creating a control to be added to "Form".
}
private void CreateLabel(string Text, int Count)
{
Label aLabel = new Label();
aLabel.Name = Text.Replace(" ", "") + "Label";
aLabel.Content = Text + ": ";
aLabel.HorizontalAlignment = HorizontalAlignment.Right;
aLabel.VerticalAlignment = VerticalAlignment.Center;
aLabel.Margin = new Thickness(0);
aLabel.FontFamily = Form.DIN;
aLabel.FontSize = 29.333;
Grid.SetRow(aLabel, Count);
Grid.SetColumn(aLabel, 0);
Form.MainGrid.Children.Add(aLabel); //Haha! We're adding it to a Grid in "Form"!
}
}
}
var targetWindow = Application.Current.Windows.Cast<Window>().FirstOrDefault(window => window is principal) as principal;
targetWindow .BssAcesso.Background = Brushes.Transparent;
just call any control of it from your current window:
targetWindow.ABUTTON.Background = Brushes.Transparent;
How can I access one window's control (richtextbox) from another window in wpf?
I was also struggling with this when I started WPF. However, I found a nice way around it similar to the good old fashioned win forms approach (coding VB.NET, sorry). Adding on what was said earlier:
To directly change properties of objects from a module or a different class for an active window:
Public Class Whatever
Public Sub ChangeObjProperties()
' Here the window is indexed in case of multiple instances of the same
' window could possibly be open at any given time.. otherwise just use 0
Dim w As MainWindow = Application.Current.Windows(0)
w.Button1.Content = "Anything"
End Sub
End Class
You obviously have to instantiate Whatever before ChangeObjProperties() can be called in your code.
Also there is no need to worry about naming in XAML regarding object accessibility.
Just declare your control like this to make it public:
<TextBox x:Name="textBox1" x:FieldModifier="public" />
You can then access it from another control.
The default declaration of controls is non public, internal and not public!
Access of the controls from within the same assembly is hence allowed. If you want to access a control on a wpf form from another assembly you have to use the modifier attribute x:FieldModifier="public" or use the method proposed by Jean.
This may be a slightly different answer, but let's think about why we need to pass data between forms.
obviously, the reason is 'visualization'.
use Delegate or Event.
There is no need to declare an element as Public just to make it visible.
only need to be able to transform elements within a window using a delegate , on a limited basis.
To access any control in another window is so simple. Lets say to access from a Login window to MainWindow. Here is the steps:
MainWindow MW = new MainWindow(); //declare the mainwindow
MW.Label1.Content = "Hello world"; //specify what control
MW.ShowDialog(); //check what happen to that control
Good programming
I've WinForms program with 2 GUI's. I work with one GUI and open another GUI using
var gui = new FormGui("SomeVar", someOthervar);
gui.ShowDialog();
I use ShowDialog() or Show() depending on what I need to get. When I'm done I would like to pass results (sometimes it's 2 strings, sometimes it's more then that) back to the Mother GUI which called Child GUI.
What's the best way to do that? I was thinking about using global variables but not sure if that's best approach?
You can create properties on your FormGui and set those within the form. When you're done with the form, you can grab those properties from your reference to the form:
var gui = new FormGui("SomeVar", someOthervar);
gui.ShowDialog();
var result = gui.Result;
EDIT: Regarding your comment:
Say your child form has some button on it or something that the user can interact with. Or if there's a close button they click on:
private void buttonCloseClick(object sender, EventArgs e)
{
this.Result = new ResultObject()....
}
EDIT #2 Regarding your second comment:
Yes, on your FormGui class, you need to define an object called Result:
public partial class FormGui : Form
{
public ResultObject Result {get;set;}
}
ResultObject is just something I'm making up. The point being that you're in control of FormGui, so you can add any property you want, and then access it on the FormGui object.
You can add a property on the FormGui class that contains the results you want to use in the parent form.
Also, you can use the result of ShowDialog() to pass information back as well - although this is limited values of the DialogResult enum.
You can call with ShowDialog, on the child window, use a new public property to set the result, and when you close the dialog the parent GUI should be able to see the result in the next code line.
The answer by BFree is enough for your task
I am suggesting easy way to add properties to all forms
Make a new class extend it with System.Windows.Form
public class Form : System.Windows.Forms.Form
{
//add properties
}
Check your properties in your forms