I am a NOVICE and am very much struggling with what seems should be a very simple task. How do I modify a property of a MainWindow
TextBlock
, from ano
Basically there are more than 2-3 methods. Given method is quite easier to understand & handle. You can access MainWindow controls by following codes (1),(2),(3),(4).
In File: MainWindow.xaml.cs
public partial class MainWindow
{
internal static MainWindow Main; //(1) Declare object as static
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
Main =this; //(2) Defined Main (IMP)
var AnyClassORWindow=new Class1(); //Initialize another Class
AnyClassORWindow.ShowValue();
}
}
In File: Class1.cs
internal class Class1 : MainWindow //(3) Inherited
{
internal void Display()
{
MessageBox.Show(Main.TextBox1.Text); //(4) Access MainWindow Controls by adding 'Main' before it.
}
}
Notes:-
- It's good practice to use code (2) after window LOADED not in CONSTRUCTOR.
- Code (2) in constructor may leave run-time problems.
- Another simple method is to use 'ref MainWindow_field' by passing to each class's Constructor OR assign '(MainWindow) Application.Current.MainWindow' to static Main.
You need to create an instance of MainWindow
.
But there shouldn't be a reason to do that because it will be done automagically in an WPF app. Unless you have specific reason to do that (which I doubt because of this question and because you say you're a novice).
To extend on what Nathan said, I used a safe cast:
(System.Windows.Application.Current.MainWindow as MainWindow)?.TextBlock1.Text = "Setting Text from My Program";
Note the comments on the answer Nathan gave. This isn't ideal but it works.
Use MVVM pattern
to access properties of the control and modify them:
public class Student
{
public Student()
{
}
public string Name
{
get { return "Setting Text from My Program"; }
}
}
Set the DataContext
of the XAML
in the code behind:
this.DataContext = new Student();
Bind the Text property to Name:
<TextBlock Text="{Binding Name}"/>
Because nobody else has actually answered the question I'm going to tell you how to achieve what you want, but do listen to the posters who said that in a real application you would use MVVM. However there are times when you need to do what you ask so the code you need is:
((MainWindow)System.Windows.Application.Current.MainWindow).TextBlock1.Text = "Setting Text from My Program";
You can simply achieve this using MVVM. You shouldn't directly access controls in View using its name from another class. You have to use binding properties.
First of all, add a class. This will be your ViewModel. Add your properties to this class which will be binded to your input controls in your View.
Student ViewModel
public class Student
{
public string Name
{
get { return "Setting Text from My Program"; }
}
}
App.Config
Now you have add to this View Model as a resource in your App.Config file. First, add the name space reference to your app.config where your VM resides. [xmlns:local="clr-namespace:WpfApplication2]. Add your VM class as a resource by specifying your View Model class name (student).
<Application x:Class="WpfApplication2.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml"
xmlns:local="clr-namespace:WpfApplication2">
<Application.Resources>
<local:Student x:Key="Student" />
</Application.Resources>
</Application>
MainWindow.xaml
Set the DataContext
with the resource key added to App.config and set the binding to the property defined in the Student View Model.
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
DataContext="{StaticResource Student}"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TextBlock Text="{Binding Name}" Height="23" HorizontalAlignment="Left" Margin="127,124,0,0" Name="textBlock1" VerticalAlignment="Top" Width="214" />
</Grid>
</Window>