自己的UserControl的自定义属性需要在用法上进行奇怪的绑定

tim*_*use 1 wpf xaml binding user-controls

我们有一个带有简单Text属性的TickerUserControl,它代表代码的显示文本。

  1. 我们是否真的必须在UserControl中使用这些DependencyProperty模式(见下文),还是有一种更简单的方法来实现这一点?

  2. 当我们要使用UserControl和BIND将文本字段绑定到ViewModel的属性时,我们必须使用以下奇怪的绑定语法。为什么我们不能像其他所有控件一样只使用'Text =“ {Binding Text}”“'?UserControl的属性实现有问题吗?

UserControl的用法

<userControls:TickerUserControl Text="{Binding Path=Parent.DataContext.TickerText, RelativeSource={RelativeSource Self}, Mode=OneWay}"/>
Run Code Online (Sandbox Code Playgroud)

UserControl的属性实现(后面的代码)

public partial class TickerUserControl : UserControl
{
    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); } 
    }

    public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(TickerUserControl), new PropertyMetadata(""));

    // ...
}
Run Code Online (Sandbox Code Playgroud)

UserControl的XAML代码段

<UserControl x:Class="Project.UserControls.TickerUserControl"
             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" 
             DataContext="{Binding RelativeSource={RelativeSource Self}}"
             mc:Ignorable="d">
    <TextBlock Text="{Binding Text}">

        <!-- ... -->     
Run Code Online (Sandbox Code Playgroud)

解决方案

问题是在UserControl内部设置了DataContext。我删除了DataContext绑定,为UserControl添加了名称,并修改了UserControl内部的TextBox绑定。之后,我可以从外面“照常”绑定。

<userControls:TickerUserControl Text="{Binding TickerText}"/>

<UserControl x:Class="Project.UserControls.TickerUserControl"
             Name="TickerUserControl"
             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"
             mc:Ignorable="d">
    <TextBlock Text="{Binding Text, ElementName=TickerUserControl}">

        <!-- ... -->
Run Code Online (Sandbox Code Playgroud)

Dan*_*iel 5

如果要绑定属性,则需要一个依赖项属性。

要解决奇怪的绑定问题,您可以进行以下更改:

在您的用户控件中

<UserControl Name="control"...
<TextBlock Text="{Binding Text, ElementName=control}">
Run Code Online (Sandbox Code Playgroud)

然后可以像这样绑定它

<userControls:TickerUserControl Text="{Binding TickerText}"/>
Run Code Online (Sandbox Code Playgroud)