2011-03-23 151 views
2

我正面臨ListBox的ItemsSource相關問題。我正在使用WPF MVVM工具包版本0.1實現MVVM。ListBox ItemsSource不更新

當用戶雙擊某個其他元素時,我設置了一個ListBox itemSource(我在後面的代碼中處理事件並在那裏執行命令,因爲不支持將命令綁定到特定事件)。此時,通過執行該命令,會生成一個新的ObservableCollection項目,並且ListBox的ItemsSource將相應地進行更新。但目前尚未發生。 ListBox不會動態更新。可能是什麼問題?我附上relvent代碼供您參考。

XAML:

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

代碼背後:

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

目前沒有更新的項目的第二個清單:

其加倍點擊產生下一個列表項的列表:

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);*/ 

     } 
    } 

} 

任何幫助是極大的讚賞。提前致謝。

回答

5

屬性列的setter應該引發一個PropertyChanged事件。 執行INotifyPropertyChanged這樣做:MSDN INotifyPropertyChanged

我猜MVVM工具包提供這樣做很容易的一種方式(也許ViewModelBase已經實現接口...)。

編輯:實施INotifyPropertyChanged是不夠的,你必須提出由INotifyPropertyChanged創建的事件。你屬性應該是這個樣子:

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

Vivien是對的,你也應該考慮一下初始化你的收藏。當您調用GetColumns()方法時清除您的集合並添加新項目。 – blindmeis 2011-03-23 12:25:33

+0

嗨Vivien和Blindmeis,感謝您的解決方案。正如我指出的那樣,我擴展了ViewModelBase來創建顯示的MainViewModel。因此我相信INotifyPropertyChanged已經實現。此外,我沒有清楚收集。我會嘗試這樣做,並讓你知道。如果我說的是錯的,請糾正我。再次感謝。 – 2011-03-23 12:33:56

+0

我編輯了我的答案給你一個例子。 – 2011-03-23 13:01:01

2

使用observableCollection<T>代替List<T>

MSDN DOC:

WPF中提供的ObservableCollection類,它是一個內置的實現數據採集公開INotifyCollectionChanged接口。請注意,爲了完全支持從源對象向目標傳輸數據值,集合中支持可綁定屬性的每個對象還必須實現INotifyPropertyChanged接口。有關更多信息,請參閱綁定來源概述。