When using AutoCompleteBox - I have a list of items that have the matching display text - but different ID value.
[{Text:"John",Id:1},{Text:"John",Id:2},{Text:"John Doe",Id:3}]
When I select the second row (John #2) - the first value (John #1) is set to the SelectedItem
property. When selecting a distinct value (John Doe #3) - it works correctly.
My observation is that if there are more matching items - it always takes the first of them.
What can I do so that the correct item (John #2) is set to 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}}"
/>
ViewModel:
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}");
}
}
Converter:
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;
}
}
The problem was with
TryGetMatch
method searching for a matching text and then choosing the first matched item.I added a
priorityView
argument (whereSelectedItem
is passed). Therefore before searching in the rest of the ItemSource - first it checks if the currently SelectedItem is already matching the text:This was also merged into the original repository