【问题标题】:AutoCompleteBox - How to select a specific item from a collection of matching items?AutoCompleteBox - 如何从匹配项目的集合中选择特定项目?
【发布时间】:2021-04-28 10:01:47
【问题描述】:

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

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

当我选择第二行 (John #2) - 第一个值 (John #1) 设置为 SelectedItem 属性。选择不同的值(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;
    }
}

【问题讨论】:

  • 你在用什么框架> WPF Toolbox、Avalon、caliburn?这看起来像是您使用的任何第三方库的实现问题。那个绑定看起来像 hack,你为什么不绑定到虚拟机?
  • @XAMlMAX 感谢您的评论。多亏了这一点,我意识到我们正在使用 WpfToolkit 的副本。然后我去解决了这个问题并创建了(我的第一个)拉取请求github.com/dotnetprojects/WpfToolkit/pull/55。问题现已解决

标签: c# wpf binding autocompletebox


【解决方案1】:

问题在于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 进入原始存储库

【讨论】:

    猜你喜欢
    • 2014-10-30
    • 2022-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-14
    • 1970-01-01
    • 2010-10-03
    相关资源
    最近更新 更多