我想在 WPF 的 mainWindow 中访问我的控件,如按钮或文本框,但我不能这样做。
在 Windows 窗体应用程序中非常简单,您可以将该控件的修饰符设置为 True,并且您可以从该 mainWindow 的实例访问该控件,但在 WPF 中我无法声明公共控件。我怎样才能做到这一点?
我想在 WPF 的 mainWindow 中访问我的控件,如按钮或文本框,但我不能这样做。
在 Windows 窗体应用程序中非常简单,您可以将该控件的修饰符设置为 True,并且您可以从该 mainWindow 的实例访问该控件,但在 WPF 中我无法声明公共控件。我怎样才能做到这一点?
要访问另一个 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 changed it from another window";
}
}
不幸的是,WPF 的基础是数据绑定。以任何其他方式做这件事都是“违背常规”,是不好的做法,而且编码和理解通常要复杂几个数量级。
对于您手头的问题,如果您有要在视图之间共享的数据(即使它只是一个视图),请创建一个包含表示数据的属性的视图模型类,并绑定到视图中的属性。
在你的代码中,只管理你的视图模型类,不要用它的视觉控制和视觉合成来接触实际的视图。
我发现在 WPF 中,您必须将 Window 转换为 MainWindow。
看起来很复杂,其实很简单! 但是,也许不是最佳实践。
假设我们在 MainWindow 中有一个 Label1、一个 Button1,并且您有一个处理与称为 UI 的用户界面相关的任何事情的类。
我们可以有以下内容:
主窗口类:
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"!
}
}
}
var targetWindow = Application.Current.Windows.Cast<Window>().FirstOrDefault(window => window is principal) as principal;
targetWindow .BssAcesso.Background = Brushes.Transparent;
只需从当前窗口调用它的任何控件:
targetWindow.ABUTTON.Background = Brushes.Transparent;
当我开始 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 提出的方法。
这可能是一个稍微不同的答案,但让我们考虑一下为什么我们需要在表单之间传递数据。显然,原因是“可视化”。
使用委托或事件。
无需将元素声明为 Public 只是为了使其可见。只需要能够在有限的基础上使用委托来转换窗口内的元素。
访问另一个窗口中的任何控件非常简单。假设从登录窗口访问 MainWindow。以下是步骤:
MainWindow MW = new MainWindow(); //declare the mainwindow
MW.Label1.Content = "Hello world"; //specify what control
MW.ShowDialog(); //check what happen to that control
好的编程