AutoCompleteBox - 如何 select 匹配项目集合中的特定项目?

AutoCompleteBox - How to select a specific item from a collection of matching items?

使用 AutoCompleteBox 时 - 我有一个具有匹配显示文本但 ID 值不同的项目列表。

[{Text:"John",Id:1},{Text:"John",Id:2},{Text:"John Doe",Id:3}]

当我 select 第二行 (John #2) - 第一个值 (John #1) 设置为 SelectedItem 属性。当 selecting 一个不同的值时 (John Doe #3) - 它工作正常。

我的观察是,如果有更多匹配项目 - 它总是取第一个。

我该怎么做才能将正确的项目 (John #2) 设置为 SelectedItem?

<controls2:AutoCompleteBox 
   EraseTextIfNull="False"
   ValueMemberBinding="{Binding Converter={StaticResource AutocompleteItemTextConverter}}"
   ItemsSource="{Binding TestItemSource, RelativeSource={RelativeSource TemplatedParent}}"
   SelectedItem="{Binding TestSelectedItem,Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
   Text="{Binding TestText, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" 
   ItemTemplate="{Binding Source={StaticResource TestItemTemplate}}"
 />

视图模型:

public class TestItemDto
{
    public int Id { get; set; }
    public string Text { get; set; }
}

private ObservableCollection<TestItemDto> _testItemSource = new ObservableCollection<TestItemDto>
{
    new TestItemDto
    {
        Id = 1,
        Text = "John"
    },
    new TestItemDto
    {
        Id = 2,
        Text = "John"
    },
    new TestItemDto
    {
        Id = 3,
        Text = "John Doe"
    },
};

public ObservableCollection<TestItemDto> TestItemSource
{
    get => _testItemSource;
    set
    {
        _testItemSource = value;
    }
}


private string _testText;

public string TestText
{
    get { return _testText; }
    set
    {
        _testText = value;
        Console.WriteLine($"TestText:{TestText}");
    }
}

private TestItemDto _testSelectedItem;

public TestItemDto TestSelectedItem
{
    get { return _testSelectedItem; }
    set
    {
        _testSelectedItem = value;
        Console.WriteLine($"TestText:{TestSelectedItem?.Id}:{TestSelectedItem?.Text}");
    }
}

转换器:

public class AutocompleteItemTextConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var adresarSearchResultItemDto = value as TestItemDto;
        return adresarSearchResultItemDto?.Text;
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return null;
    }
}

问题出在 TryGetMatch 搜索匹配文本然后选择第一个匹配项的方法。

我添加了一个 priorityView 参数(其中传递了 SelectedItem)。因此,在搜索 ItemSource 的其余部分之前 - 首先它会检查当前 SelectedItem 是否已经匹配文本:

private object TryGetMatch(string searchText, object priorityView,ObservableCollection<object> view, AutoCompleteFilterPredicate<string> predicate)
{
    if (priorityView != null)
    {
        if (predicate(searchText, FormatValue(priorityView)))
        {
            return priorityView;
        }
    }
    
    if (view != null && view.Count > 0)
    {
        foreach (object o in view)
        {
            if (predicate(searchText, FormatValue(o)))
            {
                return o;
            }
        }
    }

    return null;
}

这也merged到原始存储库