listview не обновляется при использовании привязки данных - PullRequest
0 голосов
/ 12 ноября 2018

У меня есть класс модели Book, который содержит свойство Keywords:

public class Book : INotifyPropertyChanged
{
    private ObservableCollection<string> _keywords;
    ...
    public ObservableCollection<string> Keywords
    {
        get => _keywords;
        set
        {
            _keywords = value;
            OnPropertyChanged("Keywords");
        }
    }
}

, и в моей главной странице у меня есть 2 компонента: представление списка и комбинированный список, каждая запись которого представляет собой checkBox:

<ComboBox
    x:Name="cbb_Keywords"
    Grid.Column="2"
    Width="300"
    Margin="5,0,0,0"
    HorizontalAlignment="Left"
    ItemsSource="{Binding Source={StaticResource AllBooks}}"
    DataContext="{Binding ElementName=listBoxBooks,Path=SelectedItem,UpdateSourceTrigger=PropertyChanged}">


    <ComboBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <CheckBox Width="200" Content="{Binding}" Click="ButtonBase_OnClick">
                    <CheckBox.IsChecked>
                        <MultiBinding Converter="{StaticResource TextInListTrueFalseConverter}" Mode="OneWay">
                            <Binding ElementName="listBoxBooks" Path="SelectedItem.KeywordsForTextbox" Mode="OneWay"></Binding>
                            <Binding RelativeSource="{RelativeSource Self}" Path="Content"></Binding>
                        </MultiBinding>
                    </CheckBox.IsChecked>
                </CheckBox>
            </StackPanel>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

одностороннее связывание checkBox.IsChecked, и когда я нажимаю на флажок, он вызывает этот метод:

private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
    CheckBox cb = (CheckBox)sender;
    var content = (string)cb.Content;
    var keywords = ((Book)listBoxBooks.SelectedItem).Keywords;
    bool clicked = cb.IsChecked.Value;
    if (clicked)
        keywords.Add(content);
    else
        keywords.Remove(content);  
}

он работает более или менее, но есть 2 предупреждения:

  • иногда флажок, на котором я только что щелкнул, отображается в поле со списком, что не является ожидаемым и раздражает

  • У меня, в дополнение ккомбинированный список, другой компонент, текстовое поле, которое содержит список ключевых слов для выбранного элемента списка:

here

, нокогда я нажимаю на флажок, чтобы включить его, список, содержащий список, не обновляется ...

, поэтому я немного изменил свойство "Ключевые слова" в Книге:

public ObservableCollection<string> Keywords
{
    get => _keywords;
    set
    {
        _keywords = value;
        OnPropertyChanged("Keywords");
        OnPropertyChanged("KeywordsForTextbox");
    }
}

иСвойство KeywordsForTextbox выглядит следующим образом:

public string KeywordsForTextbox
{
    get { return string.Join(",", _keywords); }    
}

наконец, чтобы завершить, вот компонент textBox в моем MainWindow:

<TextBox x:Name="txb_Keywords"
         Grid.Column="1"
         Width="500"
         Text="{Binding ElementName=listBoxBooks,Path=SelectedItem.KeywordsForTextbox,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}" />

, почему флажок появляется в текстовом поле комбинированного списка?почему не обновилось другое текстовое поле?

спасибо.

1 Ответ

0 голосов
/ 12 ноября 2018

Проблема в том, что при изменении коллекции Ключевые слова фактическое свойство Ключевые слова не изменяется. Это все тот же объект коллекции. Изменяются только свойства объекта (Предметы).

В вашем классе Book вы можете использовать методы для добавления и удаления, а затем для уведомления об изменении свойства.

public void AddKeyword(string name)
{
    Keywords.Add(name);
    OnPropertyChanged("Keywords");
}

public void RemoveKeyword(string name)
{
    Keywords.Remove(name);
    OnPropertyChanged("Keywords");
}

Затем измените ваше событие следующим образом.

private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
    CheckBox cb = (CheckBox)sender;
    var content = (string)cb.Content;
    var book = ((Book)listBoxBooks.SelectedItem);
    bool clicked = cb.IsChecked.Value;
    if (clicked)
        book.AddKeyword(content);
    else
        book.RemoveKeyword(content);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...