如何从我自己的 .cs 文件访问 WPF MainWindow 控件

Posted

技术标签:

【中文标题】如何从我自己的 .cs 文件访问 WPF MainWindow 控件【英文标题】:How to access WPF MainWindow Controls from my own .cs file 【发布时间】:2013-06-04 18:53:06 【问题描述】:

我是一个新手,并且非常努力地完成看似非常简单的任务。如何从另一个 cs 文件修改 MainWindow TextBlock 的属性。一个精确的代码解决方案将非常有帮助。

以下是精简后的代码。我使用静态类是否会给我带来额外的问题?

在文件中: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>

在文件中:MainWindow.xaml.cs

namespace TestApp1  
  
public partial class MainWindow : Window  
      
        public MainWindow()  
          
            InitializeComponent();  
            TextBlock1.Text = "Setting Text from MainWindow";  
            MyProgram.myProgramStart();  
          
      
  

在文件中: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";
        
    
  

【问题讨论】:

【参考方案1】:

您需要创建一个MainWindow 的实例。

但不应该这样做,因为它将在 WPF 应用程序中自动完成。除非你有特定的理由这样做(我怀疑这个问题,因为你说你是新手)。

【讨论】:

【参考方案2】:

您可以使用 MVVM 轻松实现此目的。您不应该使用另一个类的名称直接访问 View 中的控件。您必须使用绑定属性。

首先,添加一个类。这将是您的 ViewModel。将您的属性添加到此类,该类将绑定到您的视图中的输入控件。

学生视图模型

public class Student

    public string Name
    
        get  return "Setting Text from My Program"; 
    

App.Config

现在您已将其作为资源添加到您的 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

设置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>

【讨论】:

【参考方案3】:

至于为什么它不能编译,我假设你得到的编译器错误是......

An object reference is required for the non-static field, method, or property 'TestApp1.MainWindow.TextBlock1'

发生这种情况是因为您尝试访问TextBlock1,就好像它是静态的一样。正如@JeffRSon 所说,首先创建一个 MainWindow 类的实例。

// Create an instance of MainWindow
var mainWindow = new MainWindow();
mainWindow.TextBlock1.Text = "Setting Text from My Program";

我假设您可能也想显示窗口...

mainWindow.ShowDialog();

【讨论】:

【参考方案4】:

使用MVVM pattern 访问控件的属性并修改它们:

public class Student

    public Student()
    
    

    public string Name
    
        get  return "Setting Text from My Program"; 
    

在后面的代码中设置XAMLDataContext

this.DataContext = new Student();

将 Text 属性绑定到名称:

<TextBlock Text="Binding Name"/>

【讨论】:

【参考方案5】:

因为没有其他人真正回答过这个问题,所以我将告诉你如何实现你想要的,但请听那些说在实际应用程序中你会使用 MVVM 的发帖人。但是,有时您需要按照您的要求做,所以您需要的代码是:

((MainWindow)System.Windows.Application.Current.MainWindow).TextBlock1.Text = "Setting Text from My Program";

【讨论】:

不错的答案,但我只想用粗体字母重复一下:“但请听那些说在实际应用程序中你会使用 MVVM 的海报。”跨度> 很好的答案,但万一有人真的错过了......“但请听那些说在实际应用程序中你会使用 MVVM 的海报”。跨度> 我根本没有得到奖金建议的概括。以这种方式需要代码隐藏有几个原因。例如自定义 style.xaml 的代码隐藏,使用过程代码在 xaml 算法不够完善的方法的样式中使用处理程序。【参考方案6】:

基本上有2-3种以上的方法。给定的方法更容易理解和处理。 您可以通过以下代码(1),(2),(3),(4)访问MainWindow控件。

在文件中: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();
    
  

在文件中: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.
         
     

注意事项:-

    最好在窗口 LOADED not in CONSTRUCTOR 之后使用代码 (2)。 构造函数中的代码 (2) 可能会留下运行时问题。 另一个简单的方法是使用“ref MainWindow_field”,方法是传递给每个类的构造函数或将“(MainWindow) Application.Current.MainWindow”分配给静态 Main。

【讨论】:

【参考方案7】:

为了延续 Nathan 所说的,我使用了一个安全的演员表:

(System.Windows.Application.Current.MainWindow as MainWindow)?.TextBlock1.Text = "Setting Text from My Program";

注意answer Nathan gave 上的 cmets。这并不理想,但很有效。

【讨论】:

以上是关于如何从我自己的 .cs 文件访问 WPF MainWindow 控件的主要内容,如果未能解决你的问题,请参考以下文章

WPF如何获取命令行参数

wpf(Application 如何创建一个事件,及其Application相关的属性)

WPF:Main方法到哪里去了?

在wpf中访问数据网格内的组合框属性

WPF 工具包向导从我的代码中的页面访问控件

wpf中资源文件字典如何使它也拥有cs文件