📅  最后修改于: 2023-12-03 15:09:44.001000             🧑  作者: Mango
在 UWP 应用程序中,我们经常需要向用户展示数据列表,并且为了方便用户查找特定项,我们通常会添加搜索栏。在本文中,我们将介绍如何实现一个带有搜索栏的列表。
我们将使用 ListView
控件来展示数据列表,使用 TextBox
控件作为搜索栏。
INotifyPropertyChanged
接口,以便我们能够及时通知界面更新。例如:public class ListItem : INotifyPropertyChanged
{
private string _title;
public string Title
{
get { return _title; }
set
{
_title = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
ListView
和 TextBox
控件,并绑定它们的属性。例如:<StackPanel>
<TextBox x:Name="txtSearch" PlaceholderText="Search"
Text="{Binding SearchText, Mode=TwoWay}"
Margin="10"/>
<ListView x:Name="listView" ItemsSource="{Binding FilteredList}"
Margin="10">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Title}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
注意,TextBox
的 Text
属性需要绑定到一个名为 SearchText
的属性,这个属性用来保存用户输入的搜索关键字。ListView
的 ItemsSource
属性需要绑定到一个名为 FilteredList
的属性,这个属性用来保存经过过滤后的列表项。
INotifyPropertyChanged
接口,并声明 SearchText
和 FilteredList
两个属性。例如:public class ListViewModel : INotifyPropertyChanged
{
private string _searchText;
public string SearchText
{
get { return _searchText; }
set
{
_searchText = value;
FilterList();
OnPropertyChanged();
}
}
private ObservableCollection<ListItem> _listItems;
public ObservableCollection<ListItem> ListItems
{
get { return _listItems; }
set
{
_listItems = value;
FilterList();
OnPropertyChanged();
}
}
private ObservableCollection<ListItem> _filteredList;
public ObservableCollection<ListItem> FilteredList
{
get { return _filteredList; }
set
{
_filteredList = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
public ListViewModel()
{
// 初始化列表数据
ListItems = new ObservableCollection<ListItem>
{
new ListItem { Title = "Item 1" },
new ListItem { Title = "Item 2" },
new ListItem { Title = "Item 3" },
//...
};
}
private void FilterList()
{
if (ListItems != null && !string.IsNullOrEmpty(SearchText))
{
var filtered = ListItems.Where(i => i.Title.ToLower().Contains(SearchText.ToLower()))
.ToList();
FilteredList = new ObservableCollection<ListItem>(filtered);
}
else
{
FilteredList = ListItems;
}
}
protected void OnPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
在 ViewModel 类的构造函数中,我们初始化列表数据。在 FilterList()
方法中,我们根据用户输入的搜索关键字过滤列表项,并保存到 FilteredList
属性中。
OnNavigatedTo
方法中,我们创建 ViewModel 对象,并将视图和 ViewModel 绑定。例如:private ListViewModel _viewModel;
protected override void OnNavigatedTo(NavigationEventArgs e)
{
_viewModel = new ListViewModel();
DataContext = _viewModel;
}
这样,我们就完成了带有搜索栏的列表的实现。
ViewModel:
public class ListViewModel : INotifyPropertyChanged
{
private string _searchText;
public string SearchText
{
get { return _searchText; }
set
{
_searchText = value;
FilterList();
OnPropertyChanged();
}
}
private ObservableCollection<ListItem> _listItems;
public ObservableCollection<ListItem> ListItems
{
get { return _listItems; }
set
{
_listItems = value;
FilterList();
OnPropertyChanged();
}
}
private ObservableCollection<ListItem> _filteredList;
public ObservableCollection<ListItem> FilteredList
{
get { return _filteredList; }
set
{
_filteredList = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
public ListViewModel()
{
// 初始化列表数据
ListItems = new ObservableCollection<ListItem>
{
new ListItem { Title = "Item 1" },
new ListItem { Title = "Item 2" },
new ListItem { Title = "Item 3" },
//...
};
}
private void FilterList()
{
if (ListItems != null && !string.IsNullOrEmpty(SearchText))
{
var filtered = ListItems.Where(i => i.Title.ToLower().Contains(SearchText.ToLower()))
.ToList();
FilteredList = new ObservableCollection<ListItem>(filtered);
}
else
{
FilteredList = ListItems;
}
}
protected void OnPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
XAML:
<StackPanel>
<TextBox x:Name="txtSearch" PlaceholderText="Search"
Text="{Binding SearchText, Mode=TwoWay}"
Margin="10"/>
<ListView x:Name="listView" ItemsSource="{Binding FilteredList}"
Margin="10">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Title}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
页面代码:
public sealed partial class MainPage : Page
{
private ListViewModel _viewModel;
public MainPage()
{
this.InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
_viewModel = new ListViewModel();
DataContext = _viewModel;
}
}
通过以上步骤,我们成功实现了一个带有搜索栏的列表。其中,ViewModel 类从列表数据中筛选符合条件的数据,视图通过绑定搜索关键字和经过过滤后的数据列表实现搜索功能。这是一种通用的、可扩展的方式,适用于各种数据列表场景。