将用户控件的属性绑定到父

时间:2017-09-01 14:25:43

标签: .net wpf vb.net xaml data-binding

我正在VB.net中开发一个WPF应用程序。在这个应用程序中:

  • 我有几个用户控件。每个用户控件都绑定到它的某些属性(user control properties)。因此,每个用户控件的DataContext都设置为自身。
  • 这些用户控件用于窗口。该窗口具有一些其他属性(window properties)。

我想要做的是将用户控件的一些元素绑定到我的window properties,这样每当我的window properties之一被更改时,用户控件中的元素就会更新。

我已经看过几个问题和文章,说它应该可以使用Dependency Property,但是,我无法让它工作。

我已经有了一个解决方案,我在其中更新代码中的属性,但是,我希望它能在xaml中自动完成。

我非常感谢任何帮助。

________________________________________________________

更新:我尝试了建议的解决方案,但我仍然无法让它工作。

这是我所拥有的最小例子:

在我的例子中:

  • BackgroundColor是用户控件中定义的属性。
  • Text是窗口中定义的属性。

如果我在窗口中创建ucLabel(我的用户控件),我可以绑定BackgroundColorText的值。在我窗口的xaml文件中,我有两种情况的例子。

我没有得到我所缺少的东西,我无法绑定所有属性。

用户控制xaml

<UserControl x:Class="ucLabel"
         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:TestProject"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<Grid>
    <Label Background="{Binding BackgroundColor, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}"/>
</Grid>

用户控制代码

Imports System.ComponentModel

Public Class ucLabel
    Implements INotifyPropertyChanged

    Private _backgroundColor As Brush

    Public Sub New()

        InitializeComponent()

    End Sub

    Public Property BackgroundColor As Brush
        Get
            Return Brushes.LightBlue
        End Get
        Set(value As Brush)
            _backgroundColor = value
            NotifyPropertyChanged("BackgroundColor")
        End Set
    End Property

#Region "Property Changed"
    Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged

    Protected Sub NotifyPropertyChanged(info As [String])
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(info))
    End Sub
#End Region
End Class

主窗口xaml

<Window x:Class="MainWindow"
    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:DependencyPropertyTest"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="50" />
        <RowDefinition Height="50" />
    </Grid.RowDefinitions>

    <!--here the user control has *only* the correct Background-->
    <local:ucLabel Grid.Row="0"/>

    <!--here the user control has *only* the correct Text-->
    <local:ucLabel Grid.Row="1" 
                   Content="{Binding Text, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window } }"/>
</Grid>

背后的主窗口代码

Imports System.ComponentModel

Class MainWindow
    Implements INotifyPropertyChanged

    Private _text As String

    Public Sub New()

        InitializeComponent()

    End Sub

    Public Property Text As String
        Get
            Return "This is a test Text"
        End Get
        Set(value As String)
            _text = value
            NotifyPropertyChanged("Text")
        End Set
    End Property

#Region "Property Changed"
    Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
    Protected Sub NotifyPropertyChanged(info As [String])
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(info))
    End Sub
#End Region
End Class

3 个答案:

答案 0 :(得分:2)

  每个用户控件的

DataContext都设置为自身

这就是你不能做到这一点的原因。当你这样做时,你打破了你的用户控制。

相反,注释掉DataContext行,并在UserControl XAML中使用{Binding UserCtlProp, RelativeSource={RelativeSource AncestorType=UserControl}}绑定。

然后Window应该负责将自己的属性绑定到UserControl的属性,再次使用RelativeSource:

<local:MyUserControl 
    SomeProperty="{Binding SomeWindowProp, RelativeSource={RelativeSource AncestorType=Window}}"
    />

答案 1 :(得分:1)

您可以使用RelativeSource

绑定到父窗口的属性
<TextBlock Text="{Binding SomePropertyOfTheWindow, RelativeSource={RelativeSource AncestorType=Window}}" />

答案 2 :(得分:1)

  

我在窗口中使用的用户控件,具有正确的背景颜色或正确的文本。

当您设置Content的{​​{1}}时,您实际上是&#34;覆盖&#34;您在XAML标记中定义的UserControl

您可以向Label添加UCText属性,并在窗口中设置此属性。

UC xaml:

UserControl

UC代码背后:

<Label Background="{Binding BackgroundColor, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}"
       Content="{Binding UCText, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}"/>

<强>窗口:

Public Shared ReadOnly UCTextProperty As DependencyProperty = DependencyProperty.Register("UCText", GetType(String), GetType(ucLabel))

Public Property UCText As String
    Get
        Return _uctext
    End Get
    Set(value As String)
        _uctext = value
        NotifyPropertyChanged("UCText")
    End Set
End Property