web-dev-qa-db-fra.com

Comment puis-je accéder à un contrôle dans WPF à partir d'une autre classe ou d'une autre fenêtre

Je souhaite accéder à mes contrôles tels que bouton ou zone de texte dans mainWindow dans WPF, mais je ne peux pas le faire.

Dans une application Windows Form, rien de plus simple, vous pouvez définir le modificateur de ce contrôle sur True et accéder à ce contrôle à partir d'une instance de cette fenêtre principale, mais dans WPF, je ne peux pas déclarer un contrôle public. Comment puis-je faire ceci?

9
Ahad aghapour

Pour les contrôles d'accès dans d'autres fenêtres WPF, vous devez déclarer ce contrôle public, la déclaration par défaut des contrôles dans WPF est publique et vous pouvez le spécifier avec le code suivant:

<TextBox x:Name="textBox1" x:FieldModifier="public" />

Et après, vous pouvez rechercher dans toutes les fenêtres actives de l'application que les fenêtres ont ce contrôle comme ceci:

foreach (Window window in Application.Current.Windows)
{
    if (window.GetType() == typeof(Window1))
    {
       (window as Window1).textBox1.Text = "I change it from another windows";
    }
}
25
Ahad aghapour

Malheureusement, les bases de WPF sont les liaisons de données. Faire autrement, c'est aller à contre-courant, c'est une mauvaise pratique et, en général, des ordres de grandeur plus complexes à coder et à comprendre.

Si vous avez des données à partager entre les vues (et même s’il s’agit d’une seule vue), créez une classe de modèle de vue contenant des propriétés pour représenter les données et liez-vous aux propriétés à partir de vos vues.

Dans votre code, gérez uniquement votre classe de modèle de vue et ne touchez pas la vue réelle avec ses contrôles visuels et sa composition visuelle.

7
eMi

J'ai trouvé que dans WPF, vous devez convertir Window en tant que MainWindow.

Ça a l'air compliqué mais c'est très facile! Cependant, peut-être pas les meilleures pratiques.

Supposons que nous ayons un Label1, un Button1 dans MainWindow, et que vous ayez une classe qui traite de tout ce qui concerne l'interface utilisateur appelée interface utilisateur.

Nous pouvons avoir ce qui suit:

MainWindow Classe:

namespace WpfApplication1
{
    public partial class MainWindow : Window
    {
        UI ui = null;
        //Here, "null" prevents an automatic instantiation of the class,
        //which may raise a Stack Overflow Exception or not.
        //If you're creating controls such as TextBoxes, Labels, Buttons... 

        public MainWindow()
        {
            InitializeComponent(); //This starts all controls created with the XAML Designer.
            ui = new UI(); //Now we can safely create an instantiation of our UI class.
            ui.Start();
        }


    }
}

Classe UI:

namespace WpfApplication1
{    
public class UI
    {
        MainWindow Form = Application.Current.Windows[0] as MainWindow;
        //Bear in mind the array! Ensure it's the correct Window you're trying to catch.

        public void Start()
        {
            Form.Label1.Content = "Yay! You made it!";
            Form.Top = 0;
            Form.Button1.Width = 50;
            //Et voilá! You have now access to the MainWindow and all it's controls
            //from a separate class/file!
            CreateLabel(text, count); //Creating a control to be added to "Form".
        }

        private void CreateLabel(string Text, int Count)
        {
            Label aLabel = new Label();
            aLabel.Name = Text.Replace(" ", "") + "Label";
            aLabel.Content = Text + ": ";
            aLabel.HorizontalAlignment = HorizontalAlignment.Right;
            aLabel.VerticalAlignment = VerticalAlignment.Center;
            aLabel.Margin = new Thickness(0);
            aLabel.FontFamily = Form.DIN;
            aLabel.FontSize = 29.333;

            Grid.SetRow(aLabel, Count);
            Grid.SetColumn(aLabel, 0);
            Form.MainGrid.Children.Add(aLabel); //Haha! We're adding it to a Grid in "Form"!
        }


    }
}
3
Rafael Ventura

J'étais également aux prises avec ce problème lorsque j'ai créé WPF. Cependant, j’ai trouvé un moyen sympa de le comparer à la bonne approche des anciennes formes de gains (codage VB.NET, désolé). Ajoutant à ce qui a été dit plus tôt:

Pour modifier directement les propriétés des objets d'un module ou d'une classe différente pour une fenêtre active:

Public Class Whatever
    Public Sub ChangeObjProperties()
        ' Here the window is indexed in case of multiple instances of the same
        ' window could possibly be open at any given time.. otherwise just use 0
        Dim w As MainWindow = Application.Current.Windows(0)
        w.Button1.Content = "Anything"
    End Sub
End Class

Vous devez évidemment instancier Whatever avant que ChangeObjProperties() puisse être appelé dans votre code.

De plus, vous n'avez pas à vous soucier de nommer dans XAML en ce qui concerne l'accessibilité aux objets.

2
Jean

Déclarez simplement votre contrôle comme ceci pour le rendre public:

<TextBox x:Name="textBox1" x:FieldModifier="public" />

Vous pouvez alors y accéder depuis un autre contrôle.

1
BlokeTech
var targetWindow = Application.Current.Windows.Cast<Window>().FirstOrDefault(window => window is principal) as principal;
targetWindow .BssAcesso.Background = Brushes.Transparent;

il suffit d'appeler n'importe quel contrôle depuis votre fenêtre actuelle:

targetWindow.ABUTTON.Background = Brushes.Transparent;

Comment puis-je accéder au contrôle d'une fenêtre (richtextbox) à partir d'une autre fenêtre de wpf?

0
BerBar

La déclaration de contrôle par défaut est non publique, interne et non publique! 

L'accès aux commandes depuis le même assemblage est donc autorisé. Si vous souhaitez accéder à un contrôle sur un formulaire wpf depuis un autre assemblage, vous devez utiliser l'attribut modificateur x: FieldModifier = "public" ou utiliser la méthode proposée par Jean.

0
Morten Finnerud