WPF VB.NET - 来自模块的MainWindow中的引用控件

时间:2013-04-30 11:53:10

标签: wpf vb.net reference module wpf-controls

我想在我的第一个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?

我用旧的WinForm方式

Module_Connection.vb:

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

4 个答案:

答案 0 :(得分:2)

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

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

为什么呢?因为UI is Not Data因此你应该将你的应用程序逻辑建立在数据项的状态上。

我建议你阅读thisthis

尝试以与使用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属性的值以确定要执行的操作。

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

<强> EDIT2:

使ViewModel绑定到不会使事情“复杂化”。它实际上简化了很多。

如何?因为你现在正在使用简单的控件来做这件事,但是你会想要对ControlTemplate内的UI元素做更多相同的事情,或者更糟糕的是DataTemplate,这就是真正出现问题的时候。

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

非最佳方法:

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>

您必须了解Button类在WPF中没有Text属性。与大多数古老的framweworks相比,WPF有一个Content Model字面任何东西都可以包含任何,几乎没有限制。将一个Text属性放到Button上会导致Button的限制只包含Text,而WPF则不然。

因此,你真正想要做的是修改Text的{​​{1}}属性(恰好在Button内部,但实际上可能在Visual Tree中的任何位置)。< / p>

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

答案 1 :(得分:0)

这应该让你进入球场:

模块:     Public Sub Connect(RyRef txtBox as TextBox)             如果txtBox.Text =“...

注意公开与私人

呼叫:     调用.Connect(MyTextBox1)

致电并且是可选的

答案 2 :(得分:0)

我会在VB.NET中回答你的问题而不提供其他方法的C#样本,如果你不习惯这样做也可能是一场艰难的斗争。

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

Private rootWindow As MainWindow = TryCast(Application.Current.MainWindow, MainWindow)

答案 3 :(得分:0)

另一种方法是:

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

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