0

我想在我的第一个 WPF 应用程序中使用模块,因为我习惯于在我之前创建的 WinForm 应用程序中使用它们。所以我有这个按钮,里面有一个文本块。

MainWindow.xaml:

<Button x:Name="Connection_Button" Width="200" Height="30" Margin="5,5,5,5">
                        <TextBlock FontSize="14" MouseDown="TextBlock_MouseDown">CONNECT</TextBlock>
                    </Button>

在 WinForms 之前,我可以通过添加 MainForm 轻松引用按钮及其文本属性。在控件之前,但是我如何通过模块在 WPF 中执行此操作,类似于下面?我什至如何在模块代码的顶部声明控件?以及 TextBlock 等控件内的元素?

Module_Connection.vb 以我的旧 WinForm 方式:

Private Sub Connect()
        If MainForm.Connection_Button.Text = "Connect" Then
        ' Code
4

4 回答 4

2

您通常不会在 WPF 中执行此操作。

将应用程序逻辑基于 UI 元素的状态并不是一个好主意。

为什么?因为UI 不是数据,因此您应该将应用程序逻辑基于数据项的状态。

我建议你阅读这个这个

尝试以与使用 winforms 相同的方式使用 WPF 是通向悲惨失败和痛苦的直接途径。

您必须接受 MVVM 并了解 DataBinding 以及 UI 如何必须始终与应用程序逻辑和数据分开。

编辑:添加代码示例(在 C# 中)

视图模型:

public class MainViewModel
{
    public string ButtonContent {get;set;} //TODO: Add Property Change Notification

    public MainViewModel()
    {
        ButtonContent = "SomeButtonContent";
    }
}

看法:

<Button Width="200" Height="30" Margin="5,5,5,5">
    <TextBlock FontSize="14" Text="{Binding ButtonContent}"/>
</Button>

代码背后:

public class MainWindow: Window
{
    public MainWindow()
    {
        InitializeComponent();
        SomeModule.Instance = new MainViewModel();
        DataContext = SomeModule.Instance;
    }
}

模块(C# 中的静态类):

public static class SomeModule
{
    public static MainViewModel Instance {get;set;}

    public void DoSomething()
    {
        if (Instance.ButtonContent == "SomeButtonContent")
            //...etc
    }
}

这就是我将 UI 与数据分开的意思。您将字符串放在 ViewModel 中,而不是 View 中,然后评估这些 ViewModel 属性的值以确定要做什么。

尽管如此,基于字符串值的应用程序逻辑似乎是一个弱解决方案。你真正需要做什么?有更好的方法,例如为此使用枚举。

编辑2:

拥有要绑定的 ViewModel 并不会使事情“复杂化”。它实际上简化了很多。

如何?因为您现在使用简单的控件来执行此操作,但随后您会希望对 a 内的 UI 元素执行相同的操作,ControlTemplate甚至更糟糕的是 a DataTemplate,这就是真正的问题出现的时候。

因此,在处理更复杂的 UI 场景之前,您必须习惯“WPF 方式”。

非最优方法:

public class MainWindow: Window
{
     public string ButtonContent
     {
         get
         {
             return this.txtButtonContent.Text;
         }
         set
         {
             this.txtButtonContent.Text = value;
         }
     }
}

<Button Width="200" Height="30" Margin="5,5,5,5">
    <TextBlock x:Name="txtButtonContent" FontSize="14" Text="Connect"/>
</Button>

您必须了解该类在 WPFButton中没有属性。Text与大多数古老的框架相比,WPF 有一个Content Model字面上任何东西都可以包含任何东西,几乎没有限制。将Text属性放入 Button 将引入 Button 仅包含 Text 的限制,而 WPF 中并非如此。

因此,您在这里真正想要做的是修改(恰好位于 Button 内部,但实际上可能位于 Visual Tree 中的任何位置)的Text属性。TextBlock

这就是为什么我提到你实际上需要一个 ViewModel 来保存你的数据这一事实,因为没有(简单的)方法可以访问位于的 UI 元素,例如在 aDataTemplate中以操作它们。您的 UI 必须始终反映应用程序数据的状态,这些数据存储在 Model 或 ViewModel 类中,而不是 UI。

于 2013-04-30T15:09:57.373 回答
0

我将在 VB.NET 中回答您的问题,并且不提供替代方法的 C# 示例,如果您不使用的话,这可能是一场艰苦的斗争。

在你的模块中声明这个,通过 rootWindow 访问控件。

Private rootWindow As MainWindow = TryCast(Application.Current.MainWindow, MainWindow)
于 2014-03-09T11:12:45.393 回答
0

这应该让你进入球场:

模块:Public Sub Connect(RyRef txtBox as TextBox) If txtBox.Text = "...

注意公共与私人

调用:调用 .Connect(MyTextBox1)

呼叫和是可选的

于 2013-04-30T14:44:22.643 回答
0

另一种方法是:

Dim mw as MainWindow = Application.Current.Windows.OfType(Of MainWindow).First

假设您有一个 MainWindow 并且只有一个 MainWindow。

于 2021-07-15T14:38:31.913 回答