listbox不是由依赖属性observalecollection更新的

本文关键字:observalecollection 更新 属性 依赖 listbox | 更新日期: 2023-09-27 18:19:37

我正在开发的功能是自动完成关键字搜索。一旦用户在搜索栏中输入了一些内容,视图模型就会调用带有关键字参数的自动完成api,以获取自动完成建议,并将其放入observalecollection容器中。这个observalecollection是一个依赖属性,它与列表框绑定以显示自动完成建议。我的问题是相关性属性填充正确,但列表框没有显示任何内容。以下是一些代码片段:

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>

非常感谢你的帮助!

listbox不是由依赖属性observalecollection更新的

尝试这个

<ListBox Name="typeahead" Grid.Row="1" ItemsSource="{Binding TypeaheadList, UpdateSourceTrigger=PropertyChanged}" Height="518" Margin="0,0,0,-518" SelectionChanged="typeahead_SelectionChanged">

我不明白为什么要在这种情况下尝试实现DependencyPropertyTypeaheadListBinding的来源,而不是目标,对吧?所以它可以是ViewModel上的一个简单属性。

您是否尝试过使用工具包中的AutoCompleteBox?如果可能性列表不大,则可以预先填充AutoCompleteBox的ItemsSource。如果你不能预先填充它,你可以向服务器发出异步请求,以便在应用程序启动时获得所有可能性。以下是一些关于使用自动完成框的博客: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);
    }
}
相关文章:
  • 没有找到相关文章