【问题标题】:How to access WPF MainWindow Controls from my own .cs file如何从我自己的 .cs 文件访问 WPF MainWindow 控件
【发布时间】: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";
        }
    }
}  

【问题讨论】:

    标签: c# wpf controls


    【解决方案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.
                     }
                 }
            

            注意事项:-

            1. 最好在窗口 LOADED not in CONSTRUCTOR 之后使用代码 (2)。
            2. 构造函数中的代码 (2) 可能会留下运行时问题。
            3. 另一个简单的方法是使用“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。这并不理想,但很有效。

              【讨论】:

                猜你喜欢
                • 2019-06-09
                • 2012-02-27
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多