c# - WPF 背后的代码 - 如何访问 UI 元素或将其传递给事件处理程序?
问题描述
无论好坏,我只在代码后面构建 WPF UI。我在堆栈面板中有一个按钮和一个文本块。单击该按钮时,会使用一些信息更新 TextBlock。如果我使 TextBlock 成为该类的成员,它将成功运行。然而,仅仅在整个地方声明全局 UI 元素感觉就像是一个简单的出路。有没有办法在 MainWindow() 中实例化 TextBlock 并且仍然可以在按钮单击事件中访问它?
以下伪代码有效:
public partial class MainWindow : Window
{
public TextBlock myTextBlock;
public MainWindow()
{
StackPanel mainStackPanel = new StackPanel();
Button myButton = new Button();
myButton.Click += NewButton_Click();
mainStackPanel.Children.Add(myTextBlock);
mainStackPanel.Children.Add(myButton);
Content = mainStackPanel;
}
private void NewGridButton_Click(object sender, RoutedEventArgs e)
{
myTextBlock.Text = "Some Text"
}
}
但是,我很好奇这些方面的事情是否也是可能的:
public partial class MainWindow : Window```
{
public MainWindow()
{
StackPanel mainStackPanel = new StackPanel();
Button myButton = new Button();
TextBlock myTextBlock = New TextBlock();
myButton.Click += NewButton_Click();
mainStackPanel.Children.Add(myTextBlock);
mainStackPanel.Children.Add(myButton);
Content = mainStackPanel;
}
private void NewGridButton_Click(object sender, RoutedEventArgs e)
{
//Somehow Access the myTextBlock from MainWindow here in order to set the text?
myTextBlock.Text = "Some Text" // This would not compile.
}
}
为简洁起见,此处的代码仅作为示例,并不具备全部功能。预先感谢您提供有关此主题的任何信息。
编辑 - 跟进。这里答案的共识似乎表明我在考虑这个问题。代表我希望使用的 UI 元素的私有类变量似乎是一种普遍接受的(不一定是懒惰的)声明和访问 UI 元素的方式。感谢所有花时间审查和评论的人。
解决方案
这是对 WPF 的严重滥用,我怀疑您已经知道这一点。但是,如果您坚持,您可以在创建 TextBlock 时为其命名:
myTextBlock.Name = "MyTextBlock";
然后,您可以随时遍历可视化树来找到它。将此答案中的代码FindChild
添加到您的课程中,然后在您的点击处理程序中执行此操作:
private void MyButton_Click(object sender, RoutedEventArgs e)
{
var textBlock = FindChild<TextBlock>(this, "MyTextBlock");
textBlock.Text = "Hello World!";
}
如果它只是您需要支持的子控件的动态创建,那么更好的解决方案是为它们创建一个字典:
private Dictionary<string, FrameworkElement> Children = new Dictionary<string, FrameworkElement>();
...然后您将使用唯一标识符将每个控件添加到其中:
TextBlock myTextBlock = new TextBlock();
this.Children["MyTextBlock"] = myTextBlock;
虽然仍然不是在 WPF 中执行此操作的“正确”方式,但至少您不再需要遍历整个树来寻找您所追求的元素:
var textBlock = this.Children["MyTextBlock"] as TextBlock;
textBlock.Text = "Hello World!";
推荐阅读
- docker - 具有 Windows AD 身份验证的无根 docker
- azure-cosmosdb - Cosmos DB 模拟器在抽取继续令牌、分段查询时挂起
- ajax - 如何使用 Ajax 从文本文件中加载数据并将其解析为变量
- unix - 删除hadoop中的文件,不包括一些文件
- spring - 当我添加 AOP/Advice 时,Spring Boot Web(Gradle 配置)中断
- angular - 角度弹出异常
- apache-kafka - Kafka Connect 和 Debezium MySQL 源码 - 如何去掉消息 Key 中的 Struct{}?
- javascript - Firebase v9 版本的 firebase.apps.length
- python - 如何获取设备的COM端口并在python中更改它
- python - AttributeError:“NoneType”对象没有属性“get_attribute”