ListBox ItemsSource не обновляется - PullRequest
2 голосов
/ 23 марта 2011

Я столкнулся с проблемой ListBox, связанной с ItemsSource. Я реализую MVVM с инструментарием WPF MVVM версии 0.1.

Я установил один элемент ListBox itemSource для обновления, когда пользователь дважды щелкает по другому элементу (я обработал событие в коде и выполнил команду там, так как привязка команды к определенным событиям не поддерживается). На этом этапе посредством выполнения команды генерируется новая коллекция элементов ObservableCollection, и ресурс ItemsBource ListBox предназначен для соответствующего обновления. Но это не происходит в данный момент. ListBox не обновляется динамически. В чем может быть проблема? Я прилагаю код привязки для вашей справки.

XAML:

Список элементов, для которых дважды щелкните, чтобы создать следующий список:

<ListBox Height="162" HorizontalAlignment="Left" Margin="10,38,0,0" Name="tablesViewList" VerticalAlignment="Top" Width="144" Background="Transparent" BorderBrush="#20EEE2E2" BorderThickness="5" Foreground="White" ItemsSource="{Binding Path=Tables}" SelectedValue="{Binding TableNameSelected, Mode=OneWayToSource}" MouseDoubleClick="tablesViewList_MouseDoubleClick"/>

Второй список предметов, которые в настоящее время не обновляются:

 <ListBox Height="153" HorizontalAlignment="Left" Margin="10,233,0,0" Name="columnList" VerticalAlignment="Top" Width="144" Background="Transparent" BorderBrush="#20EEE2E2" BorderThickness="5" Foreground="White" ItemsSource="{Binding Path=Columns, Mode=OneWay}" DisplayMemberPath="ColumnDiscriptor"></ListBox>

Код сзади:

    private void tablesViewList_MouseDoubleClick(object sender, MouseButtonEventArgs e)
    {
        MainViewModel currentViewModel = (MainViewModel)DataContext;

        MessageBox.Show("Before event command is executed");
        ICommand command = currentViewModel.PopulateColumns;
        command.Execute(null);

        MessageBox.Show(currentViewModel.TableNameSelected);
        //command.Execute();
    }

Просмотр модели:

namespace QueryBuilderMVVM.ViewModels
{
//delegate void Del();

public class MainViewModel : ViewModelBase
{
    private DelegateCommand exitCommand;

    #region Constructor

    private ColumnsModel _columns; 

    public TablesModel Tables { get; set; }
    public ControllersModel Operators { get; set; }
    public ColumnsModel Columns {

        get { return _columns; }
        set {
            _columns = value;
            OnPropertyChanged("Columns");
        } 
    }

    public string TableNameSelected{get; set;}



    public MainViewModel()
    {
        Tables = TablesModel.Current;
        Operators = ControllersModel.Current;
        Columns = ColumnsModel.ListOfColumns;
    }

    #endregion

    public ICommand ExitCommand
    {
        get
        {
            if (exitCommand == null)
            {
                exitCommand = new DelegateCommand(Exit);
            }
            return exitCommand;
        }
    }

    private void Exit()
    {
        Application.Current.Shutdown();
    }






    //Del columnsPopulateDelegate = new MainViewModel().GetColumns;


    //Method to be assigned to the delegate
    //Creates an object of type ColumnsModel
    private void GetColumns() { 

         ColumnsModel.TableNameParam = TableNameSelected;
        Columns = ColumnsModel.ListOfColumns;
    }



    private ICommand _PopulateColumns;
    public ICommand PopulateColumns
    {
        get {

            if (_PopulateColumns == null) {

                _PopulateColumns = new DelegateCommand(GetColumns); // an action of type method is passed
            }

            return _PopulateColumns;
        }

    }


}

}

Модель:

public class ColumnsModel : ObservableCollection<VisualQueryObject>
{

    private DataSourceMetaDataRetriever dataSourceTableMetadataObject;// base object to retrieve sql data
    private static ColumnsModel listOfColumns = null;
    private static object _threadLock = new Object();
    private static string tableNameParam = null;

    public static string TableNameParam
    {
        get { return ColumnsModel.tableNameParam; }
        set { ColumnsModel.tableNameParam = value; }
    }

    public static ColumnsModel ListOfColumns
    {
        get
        {
            lock (_threadLock)
                if (tableNameParam != null)
                    listOfColumns = new ColumnsModel(tableNameParam);

            return listOfColumns;
        }

    }


    public ColumnsModel(string tableName)
    {
        ColumnsModel.tableNameParam = tableName;
        Clear();

        try
        {
            dataSourceTableMetadataObject = new DataSourceMetaDataRetriever();

            List<ColumnDescriptionObject> columnsInTable = new List<ColumnDescriptionObject>();

            columnsInTable = dataSourceTableMetadataObject.getDataTableSchema("Provider=SQLOLEDB;Data Source=.;Integrated Security=SSPI;Initial Catalog=LogiwizUser", ColumnsModel.tableNameParam);

            //List<String> listOfTables = dataSourceTableMetadataObject.getDataBaseSchema("Provider=SQLOLEDB;Data Source=.;Integrated Security=SSPI;Initial Catalog=LogiwizUser");
            //List<String> listOfTables = dsm.getDataBaseSchema("G:/mytestexcel.xlsx", true);

            //ObservableCollection<VisualQueryObject> columnVisualQueryObjects = new ObservableCollection<VisualQueryObject>();

            foreach (ColumnDescriptionObject columnDescription in columnsInTable)
            {
                VisualQueryObject columnVisual = new VisualQueryObject();
                columnVisual.ColumnDiscriptor = columnDescription;
                columnVisual.LabelType = "column";

                Add(columnVisual);
            }



        }
        catch (QueryBuilderException ex)
        {
            /* Label exceptionLabel = new Label();
             exceptionLabel.Foreground = Brushes.White;
             exceptionLabel.Content = ex.ExceptionMessage;
             grid1.Children.Add(exceptionLabel);*/

        }
    }

}

Любая помощь очень ценится. Заранее спасибо.

Ответы [ 2 ]

5 голосов
/ 23 марта 2011

Установщик свойства Columns должен вызывать событие PropertyChanged.Реализуйте INotifyPropertyChanged, чтобы сделать это: MSDN INotifyPropertyChanged

Я предполагаю, что MVVM Toolkit предоставляет способ сделать это легко (возможно, ViewModelBase уже реализует интерфейс ...).

EDIT: Реализация INotifyPropertyChanged недостаточно, вам нужно вызвать событие, созданное INotifyPropertyChanged.Ваша собственность должна выглядеть примерно так:

private ColumnsModel _columns;
public ColumnsModel Columns 
{ 
  get { return _columns; } 
  set 
  { 
    _columns = value; 
    PropertyChanged("Columns"); 
  }
}
2 голосов
/ 23 марта 2011

используйте observableCollection<T> вместо List<T>

MSDN DOC:

WPF предоставляет класс ObservableCollection, который является встроенной реализацией сбора данных, который предоставляет интерфейс INotifyCollectionChanged. Обратите внимание, что для полной поддержки передачи значений данных из исходных объектов в целевые объекты каждый объект в вашей коллекции, который поддерживает привязываемые свойства, также должен реализовывать интерфейс INotifyPropertyChanged. Для получения дополнительной информации см. Обзор источников привязки.

...