Ahad aghapour
Ahad aghapour

Reputation: 2553

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

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?

Upvotes: 24

Views: 99132

Answers (9)

Ahad aghapour
Ahad aghapour

Reputation: 2553

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 is Window1)
    {
        ((Window1)window).textBox1.Text = "I changed it from another window";
    }
}

or

foreach (Window window in Application.Current.Windows)
{
    if (window is Window1 window1)
    {
        window1.textBox1.Text = "I changed it from another window";
    }
}

or

using System.Linq;
...

foreach (Window1 window1 in Application.Current.Windows.OfType<Window1>())
{
    window1.textBox1.Text = "I changed it from another window";
}

Upvotes: 39

user7054854
user7054854

Reputation:

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.

Upvotes: -1

user8207463
user8207463

Reputation:

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?

Upvotes: 4

Hashim Shubber
Hashim Shubber

Reputation: 9

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

Upvotes: -2

Morten Finnerud
Morten Finnerud

Reputation: 86

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.

Upvotes: 1

Jean
Jean

Reputation: 31

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.

Upvotes: 3

Rafael Ventura
Rafael Ventura

Reputation: 314

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


    }
}

Upvotes: 5

eMi
eMi

Reputation: 5618

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.

Upvotes: 7

BlokeTech
BlokeTech

Reputation: 317

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.

Upvotes: 1

Related Questions