我正在处理的功能是关键字搜索的自动完成功能。一旦用户在搜索栏中输入内容,视图模型就会使用关键字参数调用自动完成API,以获取自动完成建议并将其放入observablecollection容器中。这个observablecollection是一个依赖属性,它与列表框绑定以显示自动完成建议。我的问题是依赖属性正确填充但列表框不显示任何内容。以下是一些代码:
xaml.cs中的数据绑定:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
searchBar.Focus();
_searchViewModel = new SearchViewModel();
DataContext = _searchViewModel;
}
调用视图模型中的方法来调用自动完成API:
private void searchBar_TextChanged(object sender, TextChangedEventArgs e)
{
_searchViewModel.getTypeaheadListFromServer(searchBar.Text);
}
视图模型中的依赖属性,它已成功填充:
public ObservableCollection<TypeaheadElement> TypeaheadList
{
get { return (ObservableCollection<TypeaheadElement>)GetValue(TypeaheadListProperty); }
set { SetValue(TypeaheadListProperty, value); }
}
// Using a DependencyProperty as the backing store for TypeaheadList. This enables animation, styling, binding, etc...
public static readonly DependencyProperty TypeaheadListProperty =
DependencyProperty.Register("TypeaheadList", typeof(ObservableCollection<TypeaheadElement>), typeof(SearchViewModel), new PropertyMetadata(null));
xaml中的数据绑定:
<ListBox Name="typeahead" Grid.Row="1" ItemsSource="{Binding TypeaheadList}" Height="518" Margin="0,0,0,-518" SelectionChanged="typeahead_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock TextWrapping="Wrap" Text="{Binding TypeaheadElementStr}" FontSize="{StaticResource ListItemFontSize}" FontFamily="Segoe WP" Margin="10,0,0,0" VerticalAlignment="Top">
<TextBlock.Foreground>
<SolidColorBrush Color="{StaticResource ListItemFontColor}"/>
</TextBlock.Foreground>
</TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
非常感谢你的帮助!
答案 0 :(得分:0)
试试这个
<ListBox Name="typeahead" Grid.Row="1" ItemsSource="{Binding TypeaheadList, UpdateSourceTrigger=PropertyChanged}" Height="518" Margin="0,0,0,-518" SelectionChanged="typeahead_SelectionChanged">
答案 1 :(得分:0)
我不明白为什么你试图实现DependencyProperty
就是这种情况。 TypeaheadList
是Binding
的来源,而不是目标,对吧?因此,它可以是ViewModel
上的简单属性。
答案 2 :(得分:0)
您是否尝试过使用工具包中的AutoCompleteBox?如果可能性列表不大,则可以预先填充AutoCompleteBox的ItemsSource。如果您无法预填充它,您可以向服务器发出异步请求,以便在应用启动时获得所有可能性。 以下是一些关于使用AutoCompleteBox的博客: http://www.jeff.wilcox.name/2011/03/acb-in-pivot/
如果无法做到,那么您可以执行以下操作:
的Xaml:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<toolkit:AutoCompleteBox ItemsSource="{Binding People}" Populating="AutoCompleteBox_Populating" />
</Grid>
代码:
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
People = new ObservableCollection<string> {"Shawn", "steve", "Bob", "randy", "mike"};
DataContext = this;
InitializeComponent();
}
public ObservableCollection<string> People { get; set; }
private void AutoCompleteBox_Populating(object sender, PopulatingEventArgs e)
{
// Have we already populated with this text?
if(People.Any(person => person.ToLower().StartsWith(e.Parameter.ToLower()))) return;
Completer c = new Completer();
c.Completed += new EventHandler<EventArgs>(c_Completed);
c.Complete(e.Parameter);
}
void c_Completed(object sender, EventArgs e)
{
Completer c = sender as Completer;
foreach (var name in c.Names)
{
People.Add(name);
}
}
}
internal class Completer
{
public event EventHandler<EventArgs> Completed;
public IEnumerable<string> Names { get; set; }
public void Complete(string parameter)
{
if (parameter.StartsWith("d"))
{
Names = new List<string>() { "Dick", "Dave" };
}
else if (parameter.StartsWith("j"))
{
Names = new List<string>() { "Jane", "Joe" };
}
OnCompleted();
}
protected virtual void OnCompleted()
{
var handler = Completed;
if (handler != null) handler(this, EventArgs.Empty);
}
}