【问题标题】:ListBox databinding not updating properlyListBox 数据绑定未正确更新
【发布时间】:2011-02-26 19:34:54
【问题描述】:

我得到一个奇怪的结果,当绑定到 ObservableCollection 的数据绑定到 ListBox 时,它会在视图模型构造函数中填充,但当我将相同的 ObservableCollection 填充代码移动到 @ 时不会987654324@ 事件(从视图上的事件处理程序后面的代码和 RoutedCommand 尝试)。没有async 网络服务或后台线程。

当我单步执行代码时,视图模型中的ObservableCollection 在从按钮事件调用时仍会填充,但ListBox 上的数据不会更新。两者的 XAML 相同。

这里有一些代码:

XAML

                <ListBox ItemsSource="{Binding Books}" BorderBrush="{x:Null}" Name="Results">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Vertical">
                            <TextBlock Text="{Binding Title}" FontSize="12" FontWeight="Bold" />
                            <TextBlock Text="{Binding ID}" FontSize="10" FontStyle="Italic" />
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
       ...
            <Button Command="{x:Static commands:BookQueryCommands.Query}" Content="Search" Width="119" Height="30" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0,25,0,0"/>

查看后面的代码

public partial class BookExplorer : UserControl
{
    private BookExplorerViewModel vm;

    public BookExplorer()
    {
        this.InitializeComponent();

        vm = new BookExplorerViewModel();
        this.DataContext = vm;

        this.CommandBindings.Add(new CommandBinding(BookQueryCommands.Query, ExecuteQuery));
    }

    public void ExecuteQuery(object sender, ExecutedRoutedEventArgs e) {
        vm.ExecuteBookQuery();
    }
}

视图模型

    public class BookExplorerViewModel : DependencyObject
{   
    private IBookListProvider bookProvider;
    private bool canQuery = true;

    public ObservableCollection<BookModel> Books { get; set; }
    public string Title { get; set; }
    public string ID { get; set; }
    public DateTime LastModifiedDate { get; set; }

    public BookExplorerViewModel() {
        bookProvider = new BookListProvider();
    }

    public void ExecuteBookQuery() {
        Books = bookProvider.DocumentsQuery("temp");
    }
}

// bookProvider.DocumentsQuery("temp") just fills with dummy data.
// Binding works fine if the code in ExecuteBookQuery() is in the VM constructor
// Books is still populated fine in either case just binding is not updated

型号

public class BookModel : INotifyPropertyChanged
{
    private string title;
    public string Title {
        get { return title; }
        set {
            if (value != this.title) {
                this.title = value;
                NotifyPropertyChanged(Title);
            }
        }
    }

    private string id;
    public string ID {
        get { return id; }
        set {
            if (value != this.id) {
                this.id = value;
                NotifyPropertyChanged(ID);
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(String info) {
        if (PropertyChanged != null) {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }
}

【问题讨论】:

    标签: c# wpf xaml data-binding observablecollection


    【解决方案1】:

    视图模型中的 Books 属性设置器不会触发 PropertyChanged 并且您正在绑定到它,不是吗?当您将对象分配给Books 属性时,视图会绑定到它。当您将其他内容分配给 Books 时,它是一个完全不同的对象,并且 View 不知道它,除非您触发一个表明绑定应该重新连接到这个新集合的事件。

    【讨论】:

      【解决方案2】:

      我将视图模型更改为:

      public class BookExplorerViewModel : DependencyObject
      {   
          private IBookListProvider bookProvider;
          private bool canQuery = true;
      
          public ObservableCollection<BookModel> Books { get; set; }
          public string Title { get; set; }
          public string ID { get; set; }
          public DateTime LastModifiedDate { get; set; }
      
          public BookExplorerViewModel() {
              bookProvider = new BookListProvider();            
              Books = new ObservableCollection<BookModel>(); 
          }
      
          public void ExecuteBookQuery() {
              Books.Clear();
      
              foreach(BookModel book in bookProvider.DocumentsQuery("temp")){
                  Books.Add(book);
              }
          }
      }
      

      现在可以正常使用了。

      【讨论】:

      • 继续为Books 属性分配新集合,只需确保ViewModel 也实现INotifyPropertyChanged 并在Books 设置器中触发PropertyChanged 事件。
      • @Dyppl 是正确的。您只需要告诉 WPF 绑定系统,您可以从中访问集合的属性上有一些新内容。无论您在该属性中做什么,都会触发事件,WPF 将更新绑定。
      猜你喜欢
      • 2012-07-27
      • 2011-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-28
      • 2012-06-18
      • 2011-04-21
      • 1970-01-01
      相关资源
      最近更新 更多