【问题标题】:Custom property of own UserControl needs weird binding on usage自己的 UserControl 的自定义属性在使用上需要奇怪的绑定
【发布时间】:2013-08-16 02:33:50
【问题描述】:

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

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

  2. 当我们想要使用 UserControl 并将文本字段绑定到 ViewModel 的属性时,我们必须使用以下奇怪的绑定语法。为什么我们不能像所有其他控件一样使用'Text="{Binding Text}"'? 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 sn-p

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

        <!-- ... -->

【问题讨论】:

    标签: wpf xaml binding user-controls


    【解决方案1】:

    如果你想绑定你的属性,你需要一个依赖属性。

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

    在您的用户控件中

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

    然后你就可以这样绑定了

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

    【讨论】:

    • 是的。 /签。一个缺失点(Sheridan 稍后提到):我必须删除 UserControl 内的 DataContext 绑定。我发现您的解决方案轻巧且易于记忆。谢谢!
    【解决方案2】:
    1. 如果您想在UserControl 后面的代码中创建可绑定属性,那么是的,您必须使用DependencyProperty 对象。但是,您不必在那里创建可绑定属性...您可以使用 MVVM 类型模式并在单独的类中创建可绑定属性,只要您将 该类 设置为 @987654323 @你们UserControl

    2. 不,您不必使用那种“奇怪”的绑定语法...问题是您已经硬编码将 UserControlDataContext 设置为其后面的代码.您可以像这样在控件中绑定 Text DependencyProperty 而不是这样做:

      <TextBlock Text="{Binding Text, RelativeSource={RelativeSource FindAncestor, 
      {AncestorType={x:Type Local:TickerUserControl}}}" />
      

    Local 是您本地项目的 XML 命名空间...类似这样:

         xmlns:Local="clr-namespace:Project.UserControls.TickerUserControl"
    

    那么去掉DataContext绑定后,应该可以正常从外部绑定到控件了。

    【讨论】:

    • 关键是您对 UserControl 中的 DataContext 的建议,Daniel 没有提及,但我发现他的方法更轻量级且更容易记住。谢谢谢里登!
    • 如果你真的不想选择真正解决你问题的答案,那么至少在你的问题中添加一个更新,概述完整的答案,这样你就不会误导其他用户寻找实际答案。
    • 我并不是建议您将我的答案标记为正确...您有权选择自己的最佳答案。我唯一的一点是,您应该让其他用户清楚地知道是什么解决了您的问题。
    猜你喜欢
    • 1970-01-01
    • 2010-12-04
    • 1970-01-01
    • 2011-07-19
    • 2016-12-23
    • 1970-01-01
    • 2012-03-16
    • 2017-08-21
    • 1970-01-01
    相关资源
    最近更新 更多