Как получить доступ к элементу управления в WPF из другого класса или окна

Я хочу получить доступ к моим элементам управления, таким как button или textbox в mainWindow в WPF, но я не могу этого сделать.

в Windows анкете это так легко, вы можете установить модификатор, что управление верно и вы можете достичь этого контроля, так что файл MainWindow, но в WPF я не могу объявить общественный контроль. Как я могу это сделать?

8 ответов


для элементов управления доступом в других окнах WPF необходимо объявить этот элемент управления общедоступным, объявление элементов управления по умолчанию в WPF является общедоступным, и вы можете указать его с помощью этого кода:

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

и после того, как вы можете искать во всех активных окнах в приложении, чтобы найти, чем окна имеют этот контроль, как это:

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

к сожалению, основы WPF-это привязки данных. Делать это любым другим способом-это "идти против зерна", это плохая практика и, как правило, на порядки сложнее кодировать и понимать.

к вашей проблеме под рукой, если у вас есть данные для обмена между представлениями (и даже если это только одно представление), создайте класс модели представления, который содержит свойства для представления данных, и привязать к свойствам из вашего представления(ов).

в коде, только управлять своим видом класс модели и не прикасайтесь к фактическому виду с его визуальными элементами управления и визуальной композицией.


я обнаружил, что в WPF вы должны бросить окно в качестве главного окна.

выглядит сложным, но это очень легко! однако, возможно, не лучшие практики.

предположим, что у нас есть Label1, Button1 в главном окне, и у вас есть класс, который имеет дело со всем, что связано с пользовательским интерфейсом, называемым UI.

мы можем иметь следующее:

Класса MainWindow:

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();
        }


    }
}

пользовательский интерфейс Класс:

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"!
        }


    }
}

Я также боролся с этим, когда я начал WPF. Тем не менее, я нашел хороший способ обойти его, похожий на старый добрый подход win forms (кодирование VB.NET извините). Добавив к сказанному ранее:

чтобы напрямую изменить свойства объектов из модуля или другого класса для активного окна:

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

вы явно инстанцировать Whatever до ChangeObjProperties() можно вызвать в вашем коде.

также нет необходимости беспокоиться о имен в XAML относительно доступности объекта.


просто объявите свой контроль так, чтобы сделать его общедоступным:

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

затем вы можете получить доступ к нему из другого управления.


объявление по умолчанию элементов управления является непубличным, внутренним и не публичным!

таким образом, доступ к элементам управления из одной сборки разрешен. Если вы хотите получить доступ к элементу управления в форме wpf из другой сборки, вы должны использовать атрибут модификатора x: FieldModifier="public" или использовать метод, предложенный Jean.


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

просто вызовите любой элемент управления из текущего окна:

targetWindow.ABUTTON.Background = Brushes.Transparent;

как я могу получить доступ к элементу управления одного окна (richtextbox) из другого окна в wpf?


получить доступ к любому элементу управления в другом окне так просто. Скажем, для доступа из окна входа в систему в MainWindow. Вот шаги:

MainWindow MW = new MainWindow();  //declare the mainwindow
MW.Label1.Content = "Hello world"; //specify what control
MW.ShowDialog();                   //check what happen to that control

хорошим