How can I access a control in WPF from another class or window
Asked Answered
O

9

24

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?

Oratory answered 30/11, 2012 at 11:12 Comment(2)
what you mean access to control?Expedite
Possible solution: #2219597Calceolaria
O
39

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";
    }
}
Oratory answered 16/12, 2012 at 12:55 Comment(2)
Dont know if good practice but gee it works good...using to update status bar in my main window from a user control (using FirstFloor MUI)Malik
In new class file, when i reference System.Windows and then using this foreach loop, it's throwing null reference exception as there are no windows.Knives
D
6

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.

Diwan answered 30/11, 2012 at 11:28 Comment(0)
C
5

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"!
        }


    }
}
Capp answered 16/3, 2016 at 21:13 Comment(1)
Your example worked, except that you have too much code in your example. code MainWindow mainWindow = Application.Current.Windows[0] as MainWindow; bool flag = (bool)mainWindow.chkWriteResults.IsCheckedReticular
S
4
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?

Sonorous answered 8/7, 2017 at 16:12 Comment(0)
H
3

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.

Haynes answered 27/5, 2013 at 23:53 Comment(0)
B
1

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.

Buddhi answered 30/11, 2012 at 11:22 Comment(3)
Just setting a x:Name to the desired control works out of the boxSpiritism
... and write "Public" with a capital P if you use VB :)Hoeve
It's public by default. But the question is not you are answered.Oratory
P
1

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.

Petite answered 18/4, 2017 at 8:54 Comment(0)
D
0

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.

Droll answered 16/8, 2021 at 18:35 Comment(0)
A
-1

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

Attalanta answered 26/1, 2018 at 12:10 Comment(3)
Imagine we have two forms and want to change the content of label of another form already created and opened, not a new instance of the form.Oratory
please read the accepted answers carefully. Imagine you have two forms(form1 and form2), in form1 there is a textbox and count something, now you are in the form2 and want to know the value of form1.textbox at runtime. if you create a new instance of form1, the textbox of that has the default value, but we don't want the default value.Oratory
Sorry for misunderstanding mate. ThanksAttalanta

© 2022 - 2024 — McMap. All rights reserved.