如何直接访问用户控件中的控件?

时间:2014-07-11 17:49:03

标签: wpf vb.net xaml user-controls

我的用户控件下有一个标签。以下是我的用户控件的XAML代码。

<UserControl x:Class="Class_CalcProject"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:ViewModel="clr-namespace:Class_WPFCalc_Project.WPF_Calculator.ViewModelCalculator"                 
             xmlns:local="clr-namespace:Class_WPFCalc_Project"                 
             mc:Ignorable="d"  
             d:DesignHeight="315" d:DesignWidth="650"
             Loaded="SetTextBoxFocus"
             KeyUp="KeyBoardHelper">

   <Grid>
      <Label x:Name="lblHello" />
   </Grid>
</User Control>

下面是VB.NET中用户控件的代码隐藏文件:

Import System.Data
Import System.ComponentModel
Import System.Collections
Import System.Collections.ObjectModel

Class Class_CalcProject
     Public Sub New()
           InitializeComponent()
     End Sub
End Class

我有另一个名为Testing.vb的

类文件
Import System.Data
Import System.ComponentModel
Import System.Collections
Import System.Collections.ObjectModel

Class Class_Testing

End Class

我的问题是有没有办法访问我的Label1(控件),它放在测试类的用户控件中?我可以直接更改/设置Label1的任何属性。类似的东西:

Label1.IsEnabled = True

UserControl.Current.Windows.OfType(Of Class_CalcProject)().First().Label1.IsEnabled = True

在norwal WPF应用程序中,我可以通过编写和更改/设置其属性来访问Testing Class中的标签控件:

Application.Current.Windows.OfType(Of Class_CalcProject)().First().Label1.IsEnabled = True 

在Windows WPF应用程序中,上面的代码对我来说很好。但是,当我尝试从Windows转换为用户控件时,它无法正常工作。因为我是WPF和vb.net的新手。在这方面的任何帮助将受到高度赞赏。提前感谢您发布回复。

2 个答案:

答案 0 :(得分:0)

您需要为DataContext设置UserControl类,并将其各种属性绑定到DataContext类中的属性。

最佳做法是观察MVVM模式并将ViewModel课程设为DataContext的{​​{1}}。您的测试类可能是那个需要进行一些修改的VM ...

最佳做法是使用数据绑定而不是访问后面代码中的控件属性,而不是UserControl您的XAML和Label1.IsEnabled = True属性中的<Label x:Name="lblHello" IsEnabled={Binding HelloLabelEnabled}/>而不是HelloLabelEnabled ViewModel实现某种形式的变更通知......

这就是WPF中应该如何工作......理论上,你可以继续在你的代码隐藏中对所有这些进行编码,但这是非常气馁的,并且从长远来看会让你的生活变得悲惨...... / p>

答案 1 :(得分:0)

这就是属性的用途。您不应该直接访问UserControl外的那些控件。但你可以。

.Net中的任何Control都有一个名为Controls的属性,它会立即列出父控件中的控件。你可以在扩展方法中通过一些递归来获取它们:

<Extension()> _
Public Function ChildControls(Of T As Control)(ByVal parent As Control) As List(Of T)
    Dim result As New List(Of Control)
    For Each ctrl As Control In parent.Controls
        If TypeOf ctrl Is T Then result.Add(ctrl)
        result.AddRange(ctrl.ChildControls(Of T)())
    Next
    Return result.ToArray().Select(Of T)(Function(arg1) CType(arg1, T)).ToList()
End Function

此方法从父级返回所有子控件。从这里开始,您需要通过名称获取您正在寻找的控件。用法:

Dim myLabel = CType(TeradiodeTestPanel1.ChildControls.Where(Function(c) c.Name = "Label1").Single(), Label)

如果找不到控件,Single方法将抛出异常,因此请尝试相应的Catch。