首页 > 解决方案 > 使用数据绑定时列表视图未刷新

问题描述

我有一个模型类 Book,它包含一个关键字属性:

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

在我的 MainPage 中,我有 2 个组件:一个列表视图和一个组合框,其每个条目都是一个复选框:

<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);  
}

它或多或少地工作,但有两个警告:

这里

但是当我单击一个复选框来对此进行切换时,包含该列表的列表框不会刷新...

所以我在书中修改了一些我的关键字属性:

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

和 KeywordsForTextbox 属性是这样的:

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

最后,要完整,这是我的 MainWindow 中的 textBox 组件:

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

为什么复选框出现在组合框的文本框中?为什么不刷新其他文本框?

谢谢你。

标签: c#wpfdata-binding

解决方案


问题是在修改关键字集合时,实际的关键字属性不会改变。它仍然是同一个集合对象。只有对象的属性(项目)会改变。

在您的 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);
}

推荐阅读