我有一个文本框可以使用textbox_textchanging和listview进行搜索。当用户输入字母o
时,它会在列表视图上显示字母omapukis
的搜索结果,当用户输入单词omapukis
时,它会显示来自字词{的搜索结果{1}}。
XAML:
<TextBox
x:Name="searchBox"
Grid.Row="0"
Margin="10,0,10,10"
Text=""
Foreground="Black"
Background="#E6FDFDFD"
BorderBrush="#FF7A7A7A"
PlaceholderText="Search in Indonesia Products & Bussiness"
FontFamily="Segoe UI Black"
FontSize="16"
TextChanging="searchBox_TextChanging" />
<ListView
x:Name="suggestionList"
Grid.RowSpan="2"
Grid.Column="1"
Margin="67,75,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Width="1135" Height="400"
Background="White"
BorderBrush="Black"
BorderThickness="1"
Visibility="Collapsed"
AutomationProperties.AutomationId="ItemsListView"
AutomationProperties.Name="Items"
ItemsSource="{Binding Source={StaticResource itemsViewSource}}"
IsItemClickEnabled="True"
ItemClick="suggestionList_ItemClick">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" >
<TextBlock
x:Name="Nama"
Text="{Binding Title}"
Style="{StaticResource TitleTextBlockStyle}"
TextWrapping="NoWrap"
Visibility="Visible"
Foreground="Black"
HorizontalAlignment="Left"
Margin="10,0,10,10"
SelectionHighlightColor="#FFBFA342"
FontSize="16"/>
<TextBlock
Text="{Binding ID}"
Style="{StaticResource CaptionTextBlockStyle}"
TextWrapping="NoWrap"
Visibility="Collapsed"
Foreground="#FFAAAAAA"/>
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemContainerStyle>
<Style TargetType="FrameworkElement">
<Setter Property="Margin" Value="0,0,0,5"/>
</Style>
</ListView.ItemContainerStyle>
</ListView>
代码:
ObservableCollection<SearchClass> suggestionDatasourceDetail = new ObservableCollection<SearchClass>();
ObservableCollection<SearchClass> historyDatasourceDetail = new ObservableCollection<SearchClass>();
private async void searchBox_TextChanging(TextBox sender, TextBoxTextChangingEventArgs args)
{
string keyword = searchBox.Text;
suggestionList.ItemsSource = null;
suggestionList.Items.Clear();
suggestionDatasourceDetail.Clear();
koneksiErrorStack.Visibility = Visibility.Collapsed;
requestErrorStack.Visibility = Visibility.Collapsed;
ConnectionProfile connections = NetworkInformation.GetInternetConnectionProfile();
if (connections != null && connections.GetNetworkConnectivityLevel() == NetworkConnectivityLevel.InternetAccess)
{
itemGridView.Visibility = Visibility.Visible;
busyIndicator.IsActive = true;
try
{
string urlPath = "http://.../suggest.json?q=" + keyword + "&module=listings&page=1&token=3f63-dc43-c8d5-eb45-8cbf-b72d-9d98-800f";
var httpClient = new HttpClient(new HttpClientHandler());
var values = new List<KeyValuePair<string, string>>{};
HttpResponseMessage response = await httpClient.GetAsync(urlPath);
response.EnsureSuccessStatusCode();
if (!response.IsSuccessStatusCode)
{
busyIndicator.IsActive = false;
RequestException();
}
string jsonText = await response.Content.ReadAsStringAsync();
JsonObject jsonObject = JsonObject.Parse(jsonText);
JsonArray jsonData = jsonObject["data"].GetArray();
foreach (JsonValue groupValue1 in jsonData)
{
JsonObject groupObject2 = groupValue1.GetObject();
double id = groupObject2["id"].GetNumber();
string title = groupObject2["title"].GetString();
string type = groupObject2.ContainsKey("type") && groupObject2["type"] != null ? groupObject2["type"].GetString() : string.Empty;
SearchClass file1 = new SearchClass();
file1.ID = Convert.ToInt32(id);
file1.Title = title;
if (type != string.Empty)
{
file1.Type = type;
}
if (file1.Type != "blog")
{
suggestionDatasourceDetail.Add(file1);
}
}
suggestionList.ItemsSource = searchDatasourceDetail;
if (suggestionDatasourceDetail.Count == 0)
{
busyIndicator.IsActive = false;
loading.Visibility = Visibility.Collapsed;
suggestionList.Visibility = Visibility.Collapsed;
}
else
{
busyIndicator.IsActive = false;
loading.Visibility = Visibility.Collapsed;
suggestionList.Visibility = Visibility.Visible;
}
}
catch (HttpRequestException ex)
{
busyIndicator.IsActive = false;
loading.Visibility = Visibility.Collapsed;
RequestException();
suggestionList.Visibility = Visibility.Collapsed;
}
}
else
{
busyIndicator.IsActive = false;
loading.Visibility = Visibility.Collapsed;
ConnectionException();
suggestionList.Visibility = Visibility.Collapsed;
}
}
我遇到问题,在输入字母o
时,它会在列表视图上显示字母o
的搜索结果,而当用户输入omapukis
时,则会显示搜索结果结果将显示自o
,om
,oma
,oma
,omapukis
。我想仅显示单词omapukis
的搜索结果(搜索结果只包含最后一个字母或单词)
然后,我搜索单词kalingga
,搜索结果将显示在om
,oma
,oma
,omapukis
,ka
,kali
,kalingga
。我想仅显示单词kalingga
的搜索结果(搜索结果仅包含最后一个字母或单词)。
如何解决这个问题,以便只在用户输入的最后一个字母或单词的列表视图中显示搜索结果?
答案 0 :(得分:1)
您应该使用AutoSuggestBox:https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.controls.autosuggestbox并使用TaskCancellation进行上一次搜索。基本上有一个逻辑来取消之前的搜索,以防用户修改了AutoSuggestBox上的任何内容。像这样......
private CancellationTokenSource CTS = new CancellationTokenSource();
public async Task StartSearch(string query)
{
this.CTS.Cancel(true);
this.CTS = new CancellationTokenSource();
try
{
await Task.Run(() =>
{
try
{
if (this.CTS.IsCancellationRequested)
{
return;
}
// Your actual searching logic... If you decide to update the UI here then make sure this runs on UI Thread.
if (this.CTS.IsCancellationRequested)
{
return;
}
}
catch (Exception ex)
{
// Logger...
}
}, this.CTS.Token);
}
catch (TaskCanceledException taskCnclErr)
{
// You can ignore this error
}
catch (Exception ex)
{
//Logger...
throw;
}
finally
{
}
}
现在,将StartSearch()方法挂钩到AutoSuggestBox的事件触发器 TextChanged或QuerySubmitted
答案 1 :(得分:0)
您可以在搜索数据之前等待一会儿。尝试在TextChanging
方法的开头添加此代码段(将_lockable
添加为object
类型的私有字段):
lock (_lockable)
{
var term = searchBox.Text;
await Task.Delay(250);
if (term != searchBox.Text)
return;
}
用户在开始搜索之前输入文本后,将等待四分之一秒。如果术语发生变化,则只会搜索新术语。尝试尝试延迟时间以找到适合您的方案的最佳时间。