Как получить доступ к элементам управления WPF MainWindow из моего собственного файла .cs
Я NOVICE, и я очень сильно борюсь с тем, что кажется, должно быть очень простой задачей. Как изменить свойство MainWindow
TextBlock
, из другого cs файла. Точное решение кода было бы очень полезно.
Ниже приведен урезанный код. Является ли использование статического класса причиной дополнительных проблем?
В файле: 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
Поскольку никто другой не ответил на этот вопрос, я расскажу вам, как добиться того, чего вы хотите, но послушайте плакаты, которые сказали, что в реальном приложении вы будете использовать MVVM. Однако есть моменты, когда вам нужно делать то, что вы просите, поэтому вам нужен код:
((MainWindow)System.Windows.Application.Current.MainWindow).TextBlock1.Text = "Setting Text from My Program";
Ответ 2
Вы можете просто добиться этого с помощью MVVM. Вы не должны напрямую обращаться к элементам управления в представлении, используя его имя из другого класса. Вы должны использовать свойства привязки.
Прежде всего добавьте класс, это будет ваш ViewModel. Добавьте свои свойства в этот класс, который будет привязан к вашим элементам управления в вашем представлении.
Студенческий ViewModel
public class Student
{
public string Name
{
get { return "Setting Text from My Program"; }
}
}
App.Config
Теперь вы добавили эту модель View в качестве ресурса в свой файл App.Config. Сначала добавьте ссылку на пространство имен в ваш app.config, где находится ваша виртуальная машина.
[xmlns: local = "clr-namespace: WpfApplication2]. Добавьте свой класс VM в качестве ресурса, указав имя класса View Model (ученик).
<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
В основном существует более 2-3 методов. Данный метод легче понять и обработать.
Вы можете получить доступ к элементам MainWindow с помощью следующих кодов (1), (2), (3), (4).
В файле: 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.
}
}
Примечания: -
- Хорошая практика использовать код (2) после того, как окно LOADED не находится в CONSTRUCTOR.
- Код (2) в конструкторе может оставить проблемы во время выполнения.
- Еще один простой метод - использовать 'ref MainWindow_field', передавая каждому классу конструктор ИЛИ назначая '(MainWindow) Application.Current.MainWindow' для статического Main.
Ответ 4
Используйте MVVM pattern
для доступа к свойствам элемента управления и их изменения:
public class Student
{
public Student()
{
}
public string Name
{
get { return "Setting Text from My Program"; }
}
}
Установите DataContext
в XAML
в коде позади:
this.DataContext = new Student();
Привяжите свойство Text к имени:
<TextBlock Text="{Binding Name}"/>
Ответ 5
Вам нужно создать экземпляр MainWindow
.
Но не должно быть причин для этого, потому что это будет сделано автоматически в приложении WPF. Если у вас нет особых причин для этого (что я сомневаюсь из-за этого вопроса и потому, что вы говорите, что вы новичок).
Ответ 6
Что касается того, почему он не будет компилироваться, я предполагаю, что ошибка компилятора, которую вы получаете, является...
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();