Свойство привязки обновляется только в коде, но не в пользовательском интерфейсе

#c# #wpf #xaml #data-binding

#c# #wpf #xaml #привязка к данным

Вопрос:

Предыстория: На мой взгляд, у меня есть а TextBlock и а TextBox . Как только текст изменяется в текстовом поле TextChanged , событие запускается, и после фильтрации списка я хочу обновить свойство, которое привязано к текстовому блоку.
В моем случае это счетчик, который показывает количество контактов в текущем списке.

Проблема: когда я отлаживаю свойство (ContactsCount), оно всегда обновляется корректно, но только в коде, а не в пользовательском интерфейсе. Как ни странно, пользовательский интерфейс обновляется только после того, как я удаляю текст из текстового поля, до последнего списка, но не до фактического.

Код
Вид:

     <TextBlock Text="{Binding ContactsCount, UpdateSourceTrigger=PropertyChanged}"
               d:Text="4 Contacts"/>
    <xctk:WatermarkTextBox Text="{Binding SearchText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                           Watermark="Search Contact"
                           Margin="20,10">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="TextChanged">
                <i:InvokeCommandAction Command="{Binding Path=SearchBoxTextChanged}" />
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </xctk:WatermarkTextBox>
 

Модель представления:

 public string ContactsCount
{
    get => contactsCount;
    set
    {
        contactsCount = value;
        OnPropertyChanged(ContactsCount);
    }
}

public string SearchText
{
    get => searchText;
    set
    {
        searchText = value;
        OnPropertyChanged(SearchText);
    }
}

public CommandHandler SearchBoxTextChanged { get; set; }
SearchBoxTextChanged = new CommandHandler(TextChanged);

private void TextChanged()
{
     var filteredList = contactsList.Where(c => c.FirstName != null amp;amp; c.FirstName.Contains(searchText.ToLower(), StringComparison.OrdinalIgnoreCase) || 
                                                       c.SecondName != null amp;amp; c.SecondName.Contains(searchText.ToLower(), StringComparison.OrdinalIgnoreCase));
     Contacts = new ObservableCollection<Contact>(filteredList);
     // Bug: Doesn't update the UI after ContactsCount gets changed
     ContactsCount = $"{Contacts.Count} Contacts";
}
 

Ответ №1:

Вы не опубликовали код своего OnPropertyChanged() метода, но я подозреваю, что если должно быть

 OnPropertyChanged("SearchText");
 

или лучше

 OnPropertyChanged(nameof(SearchText));
 

т.е. передайте имя обновленного свойства, а не его значение.

Комментарии:

1. Это не реально — я действительно совершил такую глупую ошибку.. В любом случае, вы совершенно правы. В моем случае мне даже не нужно писать имя свойства, и я могу оставить параметр пустым.