Skip to content

Fix AutoCompleteBox not opening when the text box is empty #12057

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion samples/ControlCatalog/Pages/AutoCompleteBoxPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
<Setter Property="Margin" Value="8" />
</Style>
</UniformGrid.Styles>
<StackPanel>
<TextBlock Text="MinimumPrefixLength: 0" />
<AutoCompleteBox MinimumPrefixLength="0" />
</StackPanel>
<StackPanel>
<TextBlock Text="MinimumPrefixLength: 1" />
<AutoCompleteBox MinimumPrefixLength="1" />
Expand All @@ -42,7 +46,6 @@
<TextBlock Text="Disabled" />
<AutoCompleteBox IsEnabled="False" />
</StackPanel>

<StackPanel>
<TextBlock Text="ValueMemberBinding" />
<AutoCompleteBox ValueMemberBinding="{Binding Capital, x:DataType=models:StateData}" />
Expand Down
11 changes: 4 additions & 7 deletions src/Avalonia.Controls/AutoCompleteBox/AutoCompleteBox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1320,17 +1320,14 @@ private void TextUpdated(string? newText, bool userInitiated)
// Evaluate the conditions needed for completion.
// 1. Minimum prefix length
// 2. If a delay timer is in use, use it
bool populateReady = newText.Length >= MinimumPrefixLength && MinimumPrefixLength >= 0;
if (populateReady && MinimumPrefixLength == 0 && String.IsNullOrEmpty(newText) && String.IsNullOrEmpty(SearchText))
{
populateReady = false;
}
_userCalledPopulate = populateReady ? userInitiated : false;
bool minimumLengthReached = newText.Length >= MinimumPrefixLength && MinimumPrefixLength >= 0;

_userCalledPopulate = minimumLengthReached && userInitiated;

// Update the interface and values only as necessary
UpdateTextValue(newText, userInitiated);

if (populateReady)
if (minimumLengthReached)
{
_ignoreTextSelectionChange = true;

Expand Down
37 changes: 27 additions & 10 deletions tests/Avalonia.Controls.UnitTests/AutoCompleteBoxTests.cs
Original file line number Diff line number Diff line change
@@ -1,21 +1,15 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Presenters;
using Avalonia.Controls.Templates;
using Avalonia.Data;
using Avalonia.Markup.Data;
using Avalonia.Platform;
using Avalonia.Threading;
using Avalonia.UnitTests;
using Moq;
using Xunit;
using System.Collections.ObjectModel;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using Avalonia.Input;

namespace Avalonia.Controls.UnitTests
{
Expand Down Expand Up @@ -439,6 +433,29 @@ public void SelectedItem_Validation()
});
}

[Fact]
public void Explicit_Dropdown_Open_Request_MinimumPrefixLength_0()
{
RunTest((control, textbox) =>
{
control.Text = "";
control.MinimumPrefixLength = 0;
Dispatcher.UIThread.RunJobs();

Assert.False(control.IsDropDownOpen);

control.RaiseEvent(new KeyEventArgs
{
RoutedEvent = InputElement.KeyDownEvent,
Key = Key.Down
});

Dispatcher.UIThread.RunJobs();

Assert.True(control.IsDropDownOpen);
});
}

/// <summary>
/// Retrieves a defined predicate filter through a new AutoCompleteBox
/// control instance.
Expand Down Expand Up @@ -1072,14 +1089,14 @@ private void RunTest(Action<AutoCompleteBox, TextBox> test)

private AutoCompleteBox CreateControl()
{
var datePicker =
var autoCompleteBox =
new AutoCompleteBox
{
Template = CreateTemplate()
};

datePicker.ApplyTemplate();
return datePicker;
autoCompleteBox.ApplyTemplate();
return autoCompleteBox;
}
private TextBox GetTextBox(AutoCompleteBox control)
{
Expand Down