【问题标题】:listbox is not updated by dependency property observablecollection列表框没有被依赖属性 observablecollection 更新
【发布时间】:2012-01-28 04:12:00
【问题描述】:

我正在开发的功能是自动完成关键字搜索。一旦用户在搜索栏中输入内容,视图模型就会调用带有关键字参数的自动完成 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>

非常感谢您的帮助!

【问题讨论】:

    标签: c# windows-phone-7


    【解决方案1】:

    试试这个

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

    【讨论】:

    • 嗨,哈里斯,非常感谢您的帮助。但是,在添加 updatesourcetrigger 后,当我导航到该页面时,会出现这样的错误:无法从文本“PropertyChanged”创建“System.Windows.Data.UpdateSourceTrigger”。有什么建议么?谢谢!
    • 尝试将DependencyProperty.Register的最后一个参数更改为new FrameworkPropertyMetadata( null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)
    • 嗨,哈里斯,非常感谢您的回复。我尝试使用 FrameworkPropertyMetadata,但它抱怨“命名空间 System.Windows 中不存在 FrameworkPropertyMetadata。”但是,我检查了 msdn 文档,FrameworkPropertyMetadata 类就在 System.Windows 下。知道发生了什么吗?很抱歉一直问新问题。谢谢!
    • 我也收到此错误:无法从文本“PropertyChanged”创建“System.Windows.Data.UpdateSourceTrigger”如何修复?
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      您是否尝试过使用工具包中的 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);
          }
      }
      

      【讨论】:

      • 嗨,肖恩,非常感谢您的回复。但是,我认为我的自动完成 api 与示例有点不同。它不会返回所有自动完成,它会根据用户输入的内容返回自动完成。例如,它不会返回所有产品名称,但如果将“ip”发送到服务器,它将返回“iphone, ipod、ipad……”。
      • (继续上一条评论)所以在这种情况下,我认为我应该坚持我原来的方式。将自动完成的列表框绑定到视图模型中的属性,每次用户输入内容时,调用 api 以获取自动完成并填充属性。但我的问题是属性已填充但列表框未更新。 =(
      • 嗨,肖恩,没关系,我解决了这个问题。还是谢谢!
      • 自动完成的行为方式相同。它会在您键入时过滤掉值。我的示例是如何添加额外值的一个小示例。这很简单,但同样的概念也可以用于击中 serer。很高兴你发现了你的问题!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-21
      • 1970-01-01
      • 2010-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多