C# 如何从我自己的 .cs 文件访问 WPF MainWindow 控件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17001486/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to access WPF MainWindow Controls from my own .cs file
提问by John Wolfe
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 MainWindowTextBlock, from another cs file. An exact code solution would be extremely helpful.
我是一名新手,正在为看似非常简单的任务而苦苦挣扎。如何MainWindowTextBlock从另一个 cs 文件修改 a 的属性。精确的代码解决方案将非常有帮助。
Below is the stripped down code. Is my use of static class causing me extra issues?
下面是精简后的代码。我使用静态类是否会导致额外的问题?
In File: MainWindow.xaml
在文件中:MainWindow.xaml
<Window x:Class="TestApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TextBlock x:Name="TextBlock1" HorizontalAlignment="Left" Margin="107,71,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top"/>
</Grid>
</Window>
In File: MainWindow.xaml.cs
在文件中:MainWindow.xaml.cs
namespace TestApp1
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
TextBlock1.Text = "Setting Text from MainWindow";
MyProgram.myProgramStart();
}
}
}
In File: CodeFile1.cs
在文件中:CodeFile1.cs
namespace TestApp1
{
public static class MyProgram
{
public static void myProgramStart()
{
// ... blah blah blah
// I want to do something like follows, but won't compile
MainWindow.TextBlock1.Text = "Setting Text from My Program";
}
}
}
回答by JeffRSon
You need to create an instance of MainWindow.
您需要创建一个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).
但是没有理由这样做,因为它会在 WPF 应用程序中自动完成。除非你有具体的理由这样做(我怀疑是因为这个问题,因为你说你是新手)。
回答by Kurubaran
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.
您可以使用 MVVM 简单地实现这一点。您不应使用来自另一个类的名称直接访问 View 中的控件。您必须使用绑定属性。
First of all add a class, this will be your ViewModelAdd your properties to this class which will be binded to your input controls in your View.
首先添加一个类,这将是您的ViewModel将您的属性添加到这个类,该类将绑定到您的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.Configfile. 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).
现在,您已将这个视图模型作为资源添加到App.Config文件中。首先将名称空间引用添加到您的 VM 所在的 app.config 中。[xmlns:local="clr-namespace:WpfApplication2]. 通过指定您的视图模型类名称(学生),将您的 VM 类添加为资源。
<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
主窗口.xaml
Set the DataContextwith the resource key added to App.config and Set the binding to the property defined in the Student View Model.
设置DataContext与添加到App.config中,并设置绑定到学生视图模型中定义的属性的资源键。
<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>
回答by blins
As for why it won't compile, I will assume the compiler error you are getting is...
至于为什么它不会编译,我会假设你得到的编译器错误是......
An object reference is required for the non-static field, method, or property 'TestApp1.MainWindow.TextBlock1'
An object reference is required for the non-static field, method, or property 'TestApp1.MainWindow.TextBlock1'
This happens because you are trying to access an TextBlock1as if it were static. As @JeffRSon stated, create an instance of your MainWindow class first.
发生这种情况是因为您试图访问一个TextBlock1,就好像它是静态的一样。正如@JeffRSon 所说,首先创建一个 MainWindow 类的实例。
// Create an instance of MainWindow
var mainWindow = new MainWindow();
mainWindow.TextBlock1.Text = "Setting Text from My Program";
I assume you may want to display the window as well...
我想你可能也想显示窗口......
mainWindow.ShowDialog();
回答by Arushi Agrawal
Use MVVM patternto access properties of the control and modify them:
使用MVVM pattern该控件的访问属性并进行修改:
public class Student
{
public Student()
{
}
public string Name
{
get { return "Setting Text from My Program"; }
}
}
Set the DataContextof the XAMLin the code behind:
设置DataContext的XAML在后面的代码:
this.DataContext = new Student();
Bind the Text property to Name:
将 Text 属性绑定到 Name:
<TextBlock Text="{Binding Name}"/>
回答by Nathan Phillips
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:
因为没有其他人真正回答过这个问题,我将告诉你如何实现你想要的,但请听听那些说在实际应用程序中你会使用 MVVM 的海报。但是,有时您需要按照要求执行操作,因此您需要的代码是:
((MainWindow)System.Windows.Application.Current.MainWindow).TextBlock1.Text = "Setting Text from My Program";
回答by Dark Knight
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).
基本上有2-3种以上的方法。给定的方法更容易理解和处理。您可以通过以下代码 (1)、(2)、(3)、(4) 访问 MainWindow 控件。
In File: MainWindow.xaml.cs
在文件中: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
在文件中: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.
笔记:-
- 在窗口加载后而不是在构造函数中使用代码 (2) 是一种很好的做法。
- 构造函数中的代码 (2) 可能会留下运行时问题。
- 另一种简单的方法是通过传递给每个类的构造函数或将“(MainWindow) Application.Current.MainWindow”分配给静态 Main 来使用“ref MainWindow_field”。
回答by IDarkCoder
To extend on what Nathan said, I used a safe cast:
为了扩展 Nathan 所说的,我使用了一个安全的演员:
(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.

