ListBox ItemsSource不更新

时间:2011-03-23 12:11:33

标签: c# wpf mvvm mvvm-toolkit

我正面临ListBox的ItemsSource相关问题。我正在使用WPF MVVM工具包版本0.1实现MVVM。

当用户双击某个其他元素时,我将一个ListBox itemSource设置为更新(我在后面的代码中处理了事件并在那里执行了命令,因为不支持将命令绑定到特定事件)。此时,通过执行命令,将生成新的ObservableCollection项,并且ListBox的ItemsSource将相应地更新。但目前还没有发生。 ListBox不会动态更新。可能是什么问题?我附上了relvent代码供你参考。

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 个答案:

答案 0 :(得分:5)

属性列的setter应该引发PropertyChanged事件。 实现INotifyPropertyChanged:MSDN INotifyPropertyChanged

我想MVVM Toolkit提供了一种方便的方法(也许ViewModelBase已经实现了接口......)。

编辑:实现INotifyPropertyChanged是不够的,你必须提高由INotifyPropertyChanged创建的事件。你的财产应该是这样的:

private ColumnsModel _columns;
public ColumnsModel Columns 
{ 
  get { return _columns; } 
  set 
  { 
    _columns = value; 
    PropertyChanged("Columns"); 
  }
}

答案 1 :(得分:2)