web-dev-qa-db-fra.com

Comment accéder aux contrôles WPF MainWindow à partir de mon propre fichier .cs

Je suis un NOVICE et je me bats beaucoup avec ce qui semble être une tâche très simple. Comment modifier une propriété d'un MainWindowTextBlock, à partir d'un autre fichier cs. Une solution de code exacte serait extrêmement utile.

Ci-dessous, le code simplifié. Mon utilisation de la classe static me cause-t-elle des problèmes supplémentaires? 

Dans le fichier: 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>

Dans le fichier: MainWindow.xaml.cs 

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

Dans le fichier: 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";
        }
    }
}  
21
John Wolfe

Parce que personne d’autre n’a répondu à la question, je vais vous dire comment atteindre ce que vous voulez, mais écoutez les affiches qui ont dit que dans une application réelle, vous utiliseriez MVVM. Cependant, il y a des moments où vous devez faire ce que vous demandez, donc le code dont vous avez besoin est:

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

Vous pouvez simplement y parvenir en utilisant MVVM. Vous ne devez pas accéder directement aux contrôles de View en utilisant son nom depuis une autre classe. Vous devez utiliser des propriétés de liaison. 

Tout d’abord, ajoutez une classe, ce sera votre ViewModel Ajoutez vos propriétés à cette classe qui sera liée à vos contrôles d’entrée dans votre View .

Student ViewModel

public class Student
{
    public string Name
    {
        get { return "Setting Text from My Program"; }
    }
}

App.Config

Vous avez maintenant ajouté à ce modèle de vue une ressource dans votre fichier App.Config . Ajoutez d’abord la référence à l’espace de noms dans votre app.config où votre VM réside . [Xmlns: local = "espace de nom clr: WpfApplication2]. Ajoutez votre VM classe en tant que ressource en spécifiant le nom de votre classe View Model (étudiant).

<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

Définissez DataContext avec la clé de ressource ajoutée à App.config et définissez la liaison sur la propriété définie dans le modèle de vue Étudiant.

<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>
15
Kurubaran

Fondamentalement, il existe plus de 2-3 méthodes. La méthode donnée est plus facile à comprendre et à manipuler . Vous pouvez accéder aux contrôles MainWindow en suivant les codes (1), (2), (3), (4).

Dans le fichier: 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();
    }
  }

Dans le fichier: 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.
         }
     }

Remarques:-

  1. Il est recommandé d’utiliser le code (2) après l’ouverture de la fenêtre LOADED et non dans CONSTRUCTOR.
  2. Le code (2) dans le constructeur peut laisser des problèmes d'exécution.
  3. Une autre méthode simple consiste à utiliser 'ref MainWindow_field' en transmettant au constructeur de chaque classe OR assign '(MainWindow) Application.Current.MainWindow' à Main statique.
3
Dark Knight

Utilisez MVVM pattern pour accéder aux propriétés du contrôle et les modifier:

public class Student
{
    public Student()
    {
    }

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

Définissez la DataContext de la XAML dans le code derrière:

this.DataContext = new Student();

Liez la propriété Text à Name:

<TextBlock Text="{Binding Name}"/>
1
Arushi Agrawal

Pour prolonger ce que Nathan a dit, j'ai utilisé un casting sûr:

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

Notez les commentaires sur le réponse donnée par Nathan . Ce n'est pas idéal mais ça marche.

0
IDarkCoder

Vous devez créer une instance de MainWindow.

Mais il ne devrait y avoir aucune raison de le faire car cela se fera automatiquement dans une application WPF. Sauf si vous avez une raison particulière de le faire (ce dont je doute à cause de cette question et parce que vous dites que vous êtes novice).

0
JeffRSon

En ce qui concerne la raison pour laquelle il ne compile pas, je supposerai que l’erreur du compilateur que vous obtenez est ...

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

Cela se produit parce que vous essayez d'accéder à un TextBlock1 comme s'il était statique. Comme @JeffRSon l'a déclaré, créez d'abord une instance de votre classe MainWindow.

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

Je suppose que vous voudrez peut-être aussi afficher la fenêtre ...

mainWindow.ShowDialog();
0
blins