自己的UserControl的自定义属性需要使用奇怪的绑定

时间:2013-08-14 08:26:03

标签: wpf xaml binding user-controls

我们有一个带有简单Text属性的TickerUserControl,它代表了自动收报机的显示文本。

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

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

  3. UserControl的用法

    <userControls:TickerUserControl Text="{Binding Path=Parent.DataContext.TickerText, RelativeSource={RelativeSource Self}, Mode=OneWay}"/>
    

    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(""));
    
        // ...
    }
    

    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}">
    
            <!-- ... -->     
    

    解决方案

    问题是在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}">
    
            <!-- ... -->
    

2 个答案:

答案 0 :(得分:5)

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

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

在您的usercontrol中

<UserControl Name="control"...
<TextBlock Text="{Binding Text, ElementName=control}">

然后你可以像那样绑定它

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

答案 1 :(得分:1)

  1. 如果您想在UserControl后面的代码中创建可绑定属性,那么是,您必须使用DependencyProperty个对象。但是,您不必在那里创建可绑定属性...您可以使用MVVM类型模式并在单独的类中创建可绑定属性,只要将该类设置为{{ 1}你DataContext

  2. 不,您不必使用那种“奇怪的”绑定语法 ...问题是您的硬编码设置了UserControl DataContext 1}}到它后面的代码。您可以将UserControl Text绑定在控件中,而不是这样做:

    DependencyProperty
  3. <TextBlock Text="{Binding Text, RelativeSource={RelativeSource FindAncestor, {AncestorType={x:Type Local:TickerUserControl}}}" /> 是本地项目的XML命名空间......如下所示:

    Local

    然后在删除 xmlns:Local="clr-namespace:Project.UserControls.TickerUserControl" 绑定后,您应该能够从外部正常绑定到控件。