可搜索的动态组合框 WPF

时间:2021-01-30 17:13:29

标签: c# wpf data-binding combobox

我正在尝试创建一个可搜索的组合框,其中下拉项(在 ObservableCollection 中)更新为用户文本。

例如:
假设我有一个世界上所有城市的列表(10,000+),这个列表太大而无法在下拉列表中显示。此列表(最多 100 个项目)通过 API 检索,该 API 在 GET 请求中发送搜索词。 因此,当用户搜索特定城市时,可观察集合会更新以显示相关搜索词,并且数据绑定组合框也会更新。

当搜索 = "" 时,从 API 返回前 100 个城市(以 A 开头的城市)。 Observablecollection/combobox 更新为显示。
当 search = "London" 时,从 API 返回 x 名称中带有 London 的城市。 Observablecollection/combobox 已更新以显示。

目前,我有以下代码在更改搜索值时更新可观察集合(这使用 INotifyPropertyChanged)。但是,当集合和关联数据绑定组合框更新时,用户的搜索词将被删除。

public ObservableCollection<string> cities { get; set; }

private string searchString;

public string SearchString
{
    get
    {
        return searchString;
    }
    set
    {
        searchString = value;
        // Call OnPropertyChanged whenever the property is updated
        OnPropertyChanged("SearchString");
    }
}

// Create the OnPropertyChanged method to raise the event 
protected void OnPropertyChanged(string name)
{
    if (name == "SearchString")
    {
        UpdateCitiesDropdown();
    }

    PropertyChangedEventHandler handler = PropertyChanged;
    if (handler != null)
    {
        handler(this, new PropertyChangedEventArgs(name));

    }
}

public async void UpdateCitiesDropdown()
{    
    // Retrieve new cities
    List<string> newCities = await GetCities(searchString);

    // Save old cities to remove (from observable collection)
    List<string> oldCities = cities.ToList<string>();

    foreach (string city in oldCities )
    {
        cities.Remove(city );
    }

    // Add new
    foreach (string city in newCities)
    {
        cities.Add(city );
    }
}

这是带有绑定数据的当前组合框。

<ComboBox ItemsSource="{Binding cities}" Text="{Binding SearchString, UpdateSourceTrigger=PropertyChanged}" IsEditable="True"/>

有没有办法在不删除用户搜索的情况下更新可观察集合并更新组合框?

1 个答案:

答案 0 :(得分:0)

ComboBox 中预选的文本是当前选中项的文本。 在 UpdateCitiesDropdown 方法中,您将删除包括所选项目在内的所有旧城市。这就是稍后将搜索设置为空白的原因。

解决方案可以是将 SelectedCity 属性添加到您的视图模型中。

private string selectedCity;
public string SelectedCity
{
    get { return selectedCity; }
    set
    {
        selectedCity = value;
        OnPropertyChanged("SelectedCity");
    }
}

将属性绑定到 ComboBox's SelectedItem

<ComboBox ItemsSource="{Binding cities}" Text="{Binding SearchString, UpdateSourceTrigger=PropertyChanged}" SelectedItem="{Binding SelectedCity}" IsEditable="True"/>

并修改 UpdateCitiesDropdown 方法不从 SelectedItem 集合中移除 cities

...
List<string> oldCities = cities.Where(x => x != SelectedCity).ToList<string>();
...
foreach (string city in newCities)
{
    if (city != SelectedCity)
    {
        cities.Add(city);
    }
}