Проблема с UserControl с пользовательским свойством зависимости - PullRequest
5 голосов
/ 16 июня 2010

Я пишу пользовательский элемент управления со свойством зависимости для текста поиска с именем SearchText.Это свойство зависимости, потому что я хочу разрешить потребителям элемента управления использовать привязку данных.Пользовательский элемент управления содержит текстовый блок WPF, в который пользователь может ввести текст поиска.

Я мог бы использовать привязку данных для соединения свойства зависимостей SearchText пользовательского элемента управления со свойством зависимостей Text TextBox, но только для этой привязкисрабатывает, когда текстовое поле теряет фокус ввода.Я хочу, чтобы SearchText обновлялся после каждого изменения текста.Поэтому я добавил обработчик события TextChanged в пользовательский элемент управления, где для SearchText было установлено значение Text.

Моя проблема в том, что привязка SearchText не работает, источник никогда не обновляется.Что я делаю не так?

Вот соответствующая часть пользовательского элемента управления code-behind:

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

Контекст данных окна:

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

К сожалению, этот установщик не вызывается, когда я набираю текстовое поле.Есть идеи?


После подсказки Quartermeisters я удалил обработчик событий TextBox_TextChanged и установил привязку, которая синхронизирует TextBox.Text и UserControl.SearchText.

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

Thisпривязка, кажется, работает.Но теперь связь между пользовательским элементом управления и контекстом данных окна нарушена (источник никогда не обновляется).Я немного его изменил

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

, но без эффекта.

Что-нибудь особенное, что я должен позаботиться об этих "цепочечных" привязках?

Ответы [ 2 ]

5 голосов
/ 16 июня 2010

Вы можете заставить TextBox обновлять источник привязки каждый раз, когда изменяется текст, изменяя UpdateSourceTrigger на PropertyChanged со значения по умолчанию LostFocus:

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

См. Статью MSDN по Binding.UpdateSourceTrigger .


По вашему обновленному вопросу похоже, что свойство источника не обновляется, потому что вы делаете одностороннюю привязку. Вы можете сделать это связывание двусторонним в XAML, указав Mode :

<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));
0 голосов
/ 16 июня 2010

Вам необходимо указать параметр PropertyChangedCallback для конструктора UIPropertyMetadata.

Эта статья CodeProject делает именно то, что вам нужно.См. Как использовать API поиска Windows Vista из приложения WPF в http://www.codeproject.com/KB/WPF/Vista_Search_in_WPF.aspx.

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

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