Привязка данных ListBox не обновляется должным образом - PullRequest
1 голос
/ 26 февраля 2011

Я получаю странный результат, когда привязка данных к ListBox работает, когда ObservableCollection, с которым он связан, заполняется в конструкторе модели представления, но не когда я перемещаю тот же самый код ObservableCollection в Button событие (пробовал из кода за обработчиком событий в представлении и из 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();
    }
}

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

Модель

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

Ответы [ 2 ]

3 голосов
/ 26 февраля 2011

Установщик свойства Books в модели представления не срабатывает PropertyChanged, и вы привязываетесь к нему, нет?Когда вы назначаете объект свойству Books, представление привязывается к нему.Когда вы назначаете что-то еще для Books, это совершенно другой объект, и представление не имеет об этом никакого представления, если вы не запустите событие, говорящее о том, что привязка должна быть переадресована в эту новую коллекцию.

0 голосов
/ 27 февраля 2011

Я изменил модель представления на:

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

Теперь все работает нормально.

...