开发者

ListBox databinding not updating properly

I am getting a strange result where the data binding to a ListBox works when the ObservableCollection it is bound to is populated in the view model constructor but not when I move the same ObservableCollection population code to an Button event (tried from code behind event handler on the view and from a RoutedCommand). There are no async web services or background threads.

When I step through the code, the ObservableCollection in the view model is still populated when called from the button event but the data is not updated on the ListBox. The XAML is identical in both.

Here is some code:

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"/>

View code behind

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();
    }
}

ViewModel

    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

Model

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));
        }
    }
}


The Books property setter in view model doesn't fire PropertyChanged and you're binding to it, no? When you assign an object to the Books property, the View then binds to it. When you assign something else to the Books, it's an entirely different object and the View has no idea about it unless you fire an event saying that the binding should be rewired to this new collection.


I changed the view model to:

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);
        }
    }
}

It works fine now.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜