带有自定义依赖项属性的UserControl问题

时间:2010-06-16 11:23:57

标签: c# wpf data-binding properties dependencies

我正在为一个名为SearchText的搜索文本编写一个带依赖项属性的用户控件。它是一个依赖属性,因为我想允许控件的使用者使用数据绑定。用户控件包含一个WPF TextBox,用户可以在其中输入搜索文本。

我可以使用数据绑定将用户控件的SearchText依赖项属性与TextBox的Text依赖项属性相连接,但此绑定仅在文本框失去输入焦点时触发。我想要的是每次更改文本后都要更新的SearchText。 所以我在用户控件中添加了一个TextChanged事件处理程序,我在其中将SearchText设置为Text值。

我的问题是,SearchText绑定不起作用,源永远不会更新。我做错了什么?

以下是用户控件代码隐藏的相关部分:

public partial class UserControlSearchTextBox : UserControl
{
    public string SearchText
    {
        get { return (string)GetValue(SearchTextProperty); }
        set { SetValue(SearchTextProperty, value); }
    }

    public static readonly DependencyProperty SearchTextProperty =
        DependencyProperty.Register("SearchText", typeof(string), typeof(UserControlSearchTextBox), new UIPropertyMetadata(""));

    private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        SearchText = ((TextBox)sender).Text;
    }
    ...
}

包含用户控件实例的窗口将其DataContext设置为具有也称为SearchText的属性的对象。

<uc:UserControlSearchTextBox SearchText="{Binding SearchText}" />

Window的数据上下文:

public class DataSourceUserManual : DataSourceBase
{
    private string _searchText;
    public string SearchText
    {
        get { return _searchText; }
        set
        {
            _searchText = value;
            ...
            OnPropertyChanged("SearchText");
        }
    }
}

不幸的是,当我在文本框中输入时,不会调用此setter。 有什么想法吗?


在关注Quartermeisters后,我删除了TextBox_TextChanged事件处理程序并安装了一个绑定,使TextBox.Text和UserControl.SearchText保持同步。

<TextBox Text="{Binding ElementName=root, 
                        Path=SearchText, 
                        UpdateSourceTrigger=PropertyChanged}" />

这种绑定似乎有效。但是现在用户控件和窗口的数据上下文之间的绑定被破坏(源永远不会更新)。我已经改变了一点

<uc:UserControlSearchTextBox SearchText="{Binding Source={StaticResource ResourceKey=dataSource}, 
                                                  Path=SearchText}" />

但没有效果。

关于这些“链式”绑定我需要注意什么特别的事情?

2 个答案:

答案 0 :(得分:5)

通过将UpdateSourceTrigger从默认的LostFocus更改为PropertyChanged,可以强制TextBox在每次Text更改时更新绑定源:

<TextBox Text="{Binding SearchText, UpdateSourceTrigger=PropertyChanged}" />

请参阅Binding.UpdateSourceTrigger上的MSDN文章。


在您更新的问题上,看起来源属性没有更新,因为您正在进行单向绑定。您可以通过指定Mode

在XAML中双向进行绑定
<uc:UserControlSearchTextBox SearchText="{Binding Source={StaticResource ResourceKey=dataSource}, 
                                              Mode=TwoWay,
                                              Path=SearchText}" />

或者您可以在依赖项属性中指定FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,这是TextBox.Text的作用:

public static readonly DependencyProperty SearchTextProperty =
    DependencyProperty.Register("SearchText", typeof(string), typeof(UserControlSearchTextBox), new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

答案 1 :(得分:0)

您需要为PropertyChangedCallback构造函数指定UIPropertyMetadata参数。

此CodeProject文章完全符合您的要求。请参阅http://www.codeproject.com/KB/WPF/Vista_Search_in_WPF.aspx上的如何在WPF应用程序中使用Windows Vista Search API

    ...
    new UIPropertyMetadata(
        default(string), 
        new PropertyChangedCallback(TextBox_TextChanged)
    )
    ...

    static void TextBox_TextChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) {
        ...
    }