将 Class 的不同属性绑定到同一 UserControl 的两个实例

Bind different properties of a Class to two instances of the same UserControl

我创建了一个简单的 UserControl,里面有一个 TextBox,我还创建了一个 Person class,它有两个属性 'FirstName' 和 'LastName'.

我想重用相同的UserControl,但将Personclass的不同属性绑定到UserControlsTextProperty的每个实例.

所以我在 Form1 中创建了同一个 TextBox UserControl 的两个实例,方法是将它们都托管在两个单独的 ElementHost 控件中。

现在我正在尝试将第一个 TextBox UserControls TextProperty 绑定到我的 Person classes 'FirstName' 属性,并将另一个 TextBox UserControl TextProperty 绑定到我的人 classes 'LastName' 属性。我不知道该怎么做。

最终结果应该是我的 TextBox UserControl 的两个实例,一个显示 Person classes 的名字,另一个显示 Person classes 的姓氏。当我更改 Person classes FirstName 或 LastName 属性时,更改应该通过绑定反映到每个 UserControl

我知道我可以用 StackPanel 或类似的东西将两个 TextBoxs 添加到一个 UserControl 中,然后在 xaml 中设置绑定,但是那不是我想要的。有没有一种方法可以将 UserControls 绑定到其他 class 之外的其他 xaml 或返回代码?

用户控件代码 - TextBoxUC.xaml

<UserControl x:Class="TextBoxUC"
         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:local="clr-namespace:ClassPropertiesToTextBox"
         mc:Ignorable="d" 
         d:DesignHeight="30" d:DesignWidth="300">
  <Grid>
        <TextBox x:Name="tbx" />
  </Grid>
</UserControl>

Person.vbClass代码

Public Class Person
  Implements INotifyPropertyChanged

  Private _firstname As String
  Public Property FirstName() As String
    Get
        Return _firstname
    End Get
    Set(ByVal value As String)
        _firstname = value
        NotifyPropertyChanged("FirstName")
    End Set
  End Property

  Private _lastname As String
  Public Property LastName() As String
    Get
        Return _lastname
    End Get
    Set(ByVal value As String)
        _lastname = value
        NotifyPropertyChanged("LastName")
    End Set
  End Property

  Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
  Private Sub NotifyPropertyChanged(ByVal propertyName As String)
    RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
  End Sub
End Class

Form1.vbClass代码

Public Class Form1

  'first TextBox UserControl to display Persons FirstName'
  Dim WithEvents tbxFirstNameUC As TextBoxUC
  'second TextBox UserControl to display Persons LastName'
  Dim WithEvents tbxLastNameUC As TextBoxUC
  'Person class to be used'
  Dim p As Person

  Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    p = New Person
    p.FirstName = "Homer"
    p.LastName = "Simpson"


    tbxFirstNameUC = New TextBoxUC
    'Set DataContext to my Person class instance'
    tbxFirstNameUC.DataContext = p
    'Set binding of Person classes FirstName to my first instance TextBox UserControls Text Property'
    'Cant get TextBoxes TextProperty'
    tbxFirstNameUC.tbx.SetBinding(tbxFirstNameUC.tbx.Text, New Binding("FirstName", p, p.FirstName))
    'host FirstName TextBox UserControl as a child of ElementHost control'
    hostTbxFN.Child = tbxFirstNameUC


    tbxLastNameUC = New TextBoxUC
    'Set DataContext to my Person class instance'
    tbxLastNameUC.DataContext = p
    'Set binding of Person classes FirstName to my first instance TextBox UserControls Text Property'
    'Cant get TextBoxes TextProperty'
    tbxLastNameUC.tbx.SetBinding(tbxLastNameUC.tbx.Text, New Binding("LastName", p, p.LastName))
    'host LastName TextBox UserControl as a child of ElementHost control'
    hostTbxLN.Child = tbxLastNameUC
  End Sub
End Class

您可以将字符串依赖项 属性 添加到 UserControl class (TextBoxUC.xaml.vb):

Public Class TextBoxUC

    Public Property Text() As String
        Get
            Return CType(Me.GetValue(TextProperty), Boolean)
        End Get
        Set(ByVal value As String)
            Me.SetValue(TextProperty, value)
        End Set
    End Property

    Public Shared ReadOnly TextProperty As DependencyProperty = DependencyProperty.Register("Text", GetType(String), GetType(TextBoxUC), New PropertyMetadata(Nothing))
End Class

并将 UserControl (TextBoxUC.xaml) 中的 TextBox 绑定到这个:

<TextBox x:Name="tbx" Text="{Binding Text, RelativeSource={RelativeSource AncestorType=UserControl}}" />

然后您可以像往常一样将此依赖项 属性 绑定到 Person DataContext 的 属性:

<Window x:Class="Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ClassPropertiesToTextBox"
        mc:Ignorable="d"
        Title="Window1" Height="300" Width="300">
    <Window.DataContext>
        <local:Person FirstName="Mickey" LastName="Mouse" />
    </Window.DataContext>
    <StackPanel>
        <local:TextBoxUC Text="{Binding FirstName}" />
    </StackPanel>
</Window>

编辑: 或者您可以以编程方式绑定依赖关系 属性:

p = New Person
p.FirstName = "Homer"
p.LastName = "Simpson"

tbxFirstNameUC = New TextBoxUC
'Set DataContext to my Person class instance'
tbxFirstNameUC.DataContext = p
tbxFirstNameUC.SetBinding(TextBoxUC.NameProperty, New Binding("FirstName"))