2016-10-14 9 views
0

MVVM WPFプロジェクトを少し練習しています。従業員を表示するためのビュー(MainWindow)と従業員を追加するビュー(AddPersonWindow )。ObservableCollectionが別のビューで変更されたときにComboBoxが更新されない

私のMainWindowでは、ObservableCollectionにバインドされたComboBoxがあり、MainWindowのボタンからAddPersonWindowを開くことができます。しかし、AddPersonWindowからObservableCollectionに従業員を追加し、保存ボタンをクリックしてAddPerson()関数を実行すると、MainWindowのComboBoxは更新されません。 MainWindowから全く同じAddPerson()関数を実行すると、すべてが正常で、ComboBoxに新しいエントリが表示されます。私はここで何が欠けていますか?

コード:

Person.cs

class Person 
{ 
    public string Surname { get; set; } 
    public string Name { get; set; } 
    public string Street { get; set; } 
    public string HouseNumber { get; set; } 
    public string PostalCode { get; set; } 
    public string City { get; set; } 
    public string PhoneAreaCode { get; set; } 
    public string PhoneNumber { get; set; } 
    public string Email { get; set; } 
    public string FullName { get { return String.Format("{0}, {1}", Name, Surname); } } 
} 

PersonViewModel.cs

class PersonViewModel : INotifyPropertyChanged 
{ 

    public CommandHandler ButtonClick { get; set; } 

    public PersonViewModel() 
    { 
     CreatePerson(); 
    }  

    //Combobox SelectedItem 
    private Person _selectedPerson; 
    public Person SelectedPerson 
    { 
     get { return _selectedPerson; } 

     set 
     { 
      _selectedPerson = value; 
      OnPropertyChanged("SelectedPerson"); 
     } 
    }  



    public ObservableCollection<Person> PersonList { get; set; } = new ObservableCollection<Person>(); 



    public void CreatePerson() 
    {  


     foreach (string line in File.ReadLines(@"C:\some_file.csv", Encoding.GetEncoding("iso-8859-1"))) 
     { 
      string[] substrings = line.Split(','); 
      Person person = new Person { 
       Surname = substrings[0], 
       Name = substrings[1], 
       Street = substrings[2], 
       HouseNumber = substrings[3], 
       PostalCode = substrings[4], 
       City = substrings[5], 
       PhoneAreaCode = substrings[6], 
       PhoneNumber = substrings[7], 
       Email = substrings[8] }; 
       PersonList.Add(person); 
     } 

    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    protected void OnPropertyChanged(string name) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(name)); 
     } 
    } 


} 

AddPersonViewModel.cs

class AddPersonViewModel : PersonViewModel 
{ 


    public AddPersonViewModel() 
    { 
     ButtonClick = new CommandHandler(AddPerson); 
    } 

    public string EnteredSurname { get; set; } 
    public string EnteredName { get; set; } 
    public string EnteredStreet { get; set; } 
    public string EnteredHouseNumber { get; set; } 
    public string EnteredPostalCode { get; set; } 
    public string EnteredCity { get; set; } 
    public string EnteredPhoneAreaCode { get; set; } 
    public string EnteredPhoneNumber { get; set; } 
    public string EnteredEmail { get; set; } 



    public void AddPerson() 
    { 


     Person person = new Person 
     { 
      Surname = EnteredSurname, 
      Name = EnteredName, 
      Street = EnteredStreet, 
      HouseNumber = EnteredHouseNumber, 
      PostalCode = EnteredPostalCode, 
      City = EnteredCity, 
      PhoneAreaCode = EnteredPhoneAreaCode, 
      PhoneNumber = EnteredPhoneNumber, 
      Email = EnteredEmail 
     }; 
     PersonList.Add(person); 

    } 
} 

CommandHandler.cs

class CommandHandler : ICommand 
{ 

    Action ExecuteHandler; 

    public CommandHandler(Action executeHandler) 
    {    
     ExecuteHandler = executeHandler; 
    } 

    public event EventHandler CanExecuteChanged; 

    public bool CanExecute(object parameter) 
    { 
     return true; 
    } 

    public void Execute(object parameter) 
    { 
     ExecuteHandler(); 
    } 

} 

MainWindow.xaml.cs:

public MainWindow() 
    { 
     InitializeComponent(); 
     DataContext = new PersonViewModel(); 
    } 

AddPersonWindow.xaml.cs:MainWindow.xamlで

public AddPersonWindow() 
    { 
     InitializeComponent(); 
     DataContext = new AddPersonViewModel(); 
    } 

コンボボックス:AddPersonWindow.xamlで

<ComboBox Width="325" HorizontalAlignment="Left" Margin="7" Grid.Column="1" ItemsSource="{Binding PersonList}" DisplayMemberPath="FullName" SelectedItem="{Binding SelectedPerson}" IsTextSearchEnabled="True" TextSearch.TextPath="FullName" IsEditable="True" /> 

ボタン:

<Button Width="100" Height="30" Margin="15" Grid.Row="3" Grid.Column="2" HorizontalAlignment="Right" IsEnabled="True" Command="{Binding ButtonClick}">Speichern</Button> 
+4

彼らは 'PersonViewModel'の同じインスタンスを使用していますか?複数の 'PersonViewModel/AddPersonViewModel'を作成しているので、' PersonList'のインスタンスが複数あることに注意してください。 1つの 'AddPersonViewModel'を作成し、そのインスタンスを他のページ/ウィンドウに渡す必要があります。 _(コンストラクタを経由)_ –

+0

あなたは私を正しい道に導いたと思います。私はコードビハインドに 'PersonViewModel'と' AddPersonViewModel'を作成しています(元の投稿に両方のコードビハインドファイルを追加した)ので、2つの別々の 'PersonList'インスタンスが作成されている必要があります。 私はまだこれに対処する方法を見つけられませんでしたが、試し続けます! – pumuckl

+0

うわー、彼らは 'PersonList'を共有していません。 –

答えて

0

私は、トウビューモデルの間で共有されるように1つのPersonListインスタンスを共有するために管理していなかったので、私は根本的なCSVはAddPersonViewModelにファイルを直接編集することが決定しました:

class AddPersonViewModel 
{ 

    public CommandHandler ButtonClick { get; set; } 


    public AddPersonViewModel() 
    { 
     ButtonClick = new CommandHandler(AddPerson); 
    } 

    public string EnteredSurname { get; set; } 
    public string EnteredName { get; set; } 
    public string EnteredStreet { get; set; } 
    public string EnteredHouseNumber { get; set; } 
    public string EnteredPostalCode { get; set; } 
    public string EnteredCity { get; set; } 
    public string EnteredPhoneAreaCode { get; set; } 
    public string EnteredPhoneNumber { get; set; } 
    public string EnteredEmail { get; set; } 



    void AddPerson() 
    { 

     File.AppendAllText(@"C:\some_file.csv", "\r\n" + 
      EnteredSurname + "," + 
      EnteredName + "," + 
      EnteredStreet + "," + 
      EnteredHouseNumber + "," + 
      EnteredPostalCode + "," + 
      EnteredCity + "," + 
      EnteredPhoneAreaCode + "," + 
      EnteredPhoneNumber + "," + 
      EnteredEmail, 
      Encoding.GetEncoding("iso-8859-1") 
      ); 

    } 
} 
} 

コンボボックスを更新するには他のビューで人が追加された後のPersonViewModelクラスのビューでは、ボタンをクリックして実行できるメソッドを実装しました。このために、私は以下の方法を使用します:

public void RefreshPersons() 
    { 

     PersonList.Clear(); 
     foreach (string line in File.ReadLines(@"C:\Users\c.philipp\Downloads\adressbuch.csv", Encoding.GetEncoding("iso-8859-1"))) 
     { 
      string[] substrings = line.Split(','); 
      Person person = new Person 
      { 
       Surname = substrings[0], 
       Name = substrings[1], 
       Street = substrings[2], 
       HouseNumber = substrings[3], 
       PostalCode = substrings[4], 
       City = substrings[5], 
       PhoneAreaCode = substrings[6], 
       PhoneNumber = substrings[7], 
       Email = substrings[8] 
      }; 
      PersonList.Add(person); 
     } 


    } 
関連する問題