2011-03-23 11 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

속성 설정자는 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

+0

안녕 Vivien 및 Blindmeis, 솔루션 주셔서 감사합니다. 정확히 지적한대로 ViewModelBase를 확장하여 표시된 MainViewModel을 만듭니다. 따라서 INotifyPropertyChanged가 구현되었다고 생각합니다.게다가 나는 그 수집을 지우지 않았다. 나는 그 일을 시도하고 알려주지. 내가 말하는 말이 잘못되면 나를 바로 잡으십시오. 다시 한번 감사드립니다. –

+0

예를 들어 답을 편집했습니다. –

2

List<T>

MSDN DOC:

WPF 대신 observableCollection<T>를 사용할 수있는 ObservableCollection에 클래스를 제공하는 내장 데이터 수집의 구현 INotifyCollectionChanged 인터페이스를 공개합니다. 원본 개체에서 대상으로 데이터 값을 완전히 전송할 수 있도록하려면 바인딩 가능한 속성을 지원하는 컬렉션의 각 개체도 INotifyPropertyChanged 인터페이스를 구현해야합니다. 자세한 내용은 바인딩 소스 개요를 참조하십시오.

관련 문제