2017-12-11 7 views
0

私は契約のリスト(クラスAffaire)を表示する必要があるプロジェクトを持っています。 各契約にはフェーズの一覧があります(クラスフェーズ)。 バインディングを使用して2つの異なるListViewにそれぞれを表示します。 問題は、ListViewからフェーズを削除したり、Phasesが表示されているListView、またはObjectCollectionが更新されていない場合です。他のObservableCollectionを含むObservableCollectionの "Cascade"バインディング

のObservableCollection、アフェールのリストです:

は、私は2つの異なるのObservableCollectionでコンテキストを作成しました。選択アフェール中に存在する相の一覧です のObservableCollection

私のコンテキストは次のように行われる

public class Contexte : INotifyPropertyChanged 
    { 
     private Affaire selectedAffaire; 
     private Phase selectedPhase; 
     private Assemblage selectedAssemblage; 
     public Affaire SelectedAffaire 
     { 
      get { return selectedAffaire; } 
      set 
      { 
       selectedAffaire = value; 
       this.NotifyPropertyChanged("SelectedAffaire"); 
      } 
     } 
     public Phase SelectedPhase 
     { 
      get { return selectedPhase; } 
      set 
      { 
       selectedPhase = value; 
       this.NotifyPropertyChanged("SelectedPhase"); 
      } 
     } 
     public Assemblage SelectedAssemblage 
     { 
      get { return selectedAssemblage; } 
      set 
      { 
       selectedAssemblage = value; 
       this.NotifyPropertyChanged("SelectedAssemblage"); 
      } 
     } 
     private ObservableCollection<Affaire> listeDesAffaires; 
     public ObservableCollection<Affaire> ListeDesAffaires 
     { 
      get { return listeDesAffaires; } 
      set { NotifyPropertyChanged(ref listeDesAffaires, value); } 
     } 
     /**************************************************/ 

     public event PropertyChangedEventHandler PropertyChanged; 

     public void NotifyPropertyChanged(string nomPropriete) 
     { 
      if (PropertyChanged != null) 
       PropertyChanged(this, new PropertyChangedEventArgs(nomPropriete)); 
     } 

     private bool NotifyPropertyChanged<T>(ref T variable, T valeur, [CallerMemberName] string nomPropriete = null) 
     { 
      if (object.Equals(variable, valeur)) return false; 

      variable = valeur; 
      NotifyPropertyChanged(nomPropriete); 
      return true; 
     } 

    } 

私のクラスアフェール:

public class Affaire : INotifyPropertyChanged 
    { 
     public long ID { get; set; } 
     private string nom; 
     public string Nom 
     { 
      get { return this.nom; } 
      set 
      { 
       if (this.nom != value) 
       { 
        this.nom = value; 
        this.NotifyPropertyChanged("Nom"); 
       } 
      } 
     } 
     private string code; 
     public string Code 
     { 
      get { return this.code; } 
      set 
      { 
       if (this.code != value) 
       { 
        this.code = value; 
        this.NotifyPropertyChanged("Code"); 
       } 
      } 
     } 
     private string comm; 
     public string Comm 
     { 
      get { return this.comm; } 
      set 
      { 
       if (this.comm != value) 
       { 
        this.comm = value; 
        this.NotifyPropertyChanged("Comm"); 
       } 
      } 
     } 
     private ObservableCollection<Phase> listPhases; 
     public ObservableCollection<Phase> ListPhases { 
      get { return listPhases; } 
      set 
      { 
       listPhases = value; 
       if (PropertyChanged != null) 
       { 
        NotifyPropertyChanged("ListPhases"); 
       } 
      } 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 

     public void NotifyPropertyChanged(string propName) 
     { 
      if (this.PropertyChanged != null) 
       this.PropertyChanged(this, new PropertyChangedEventArgs(propName)); 
     } 
    .... 
    } 

私のクラスのフェーズ:

public class Phase : INotifyPropertyChanged 
    { 
     private string nomPhase; 
     public string NomPhase 
     { 
      get { return this.nomPhase; } 
      set 
      { 
       if (this.nomPhase != value) 
       { 
        this.nomPhase = value; 
        this.NotifyPropertyChanged("NomPhase"); 
       } 
      } 
     } 
     private int priorite; 
     public int Priorite 
     { 
      get { return this.priorite; } 
      set 
      { 
       if (this.priorite != value) 
       { 
        this.priorite = value; 
        this.NotifyPropertyChanged("Priorite"); 
       } 
      } 
     } 
     private string commPhase; 
     public string CommPhase 
     { 
      get { return this.commPhase; } 
      set 
      { 
       if (this.commPhase != value) 
       { 
        this.commPhase = value; 
        this.NotifyPropertyChanged("CommPhase"); 
       } 
      } 
     } 
     public event PropertyChangedEventHandler PropertyChanged; 

     public void NotifyPropertyChanged(string propName) 
     { 
      if (this.PropertyChanged != null) 
       this.PropertyChanged(this, new PropertyChangedEventArgs(propName)); 
     } 
     public long IdAffaire { get; set; } 
     public long ID { get; set; } 
     private ObservableCollection<Assemblage> listAssemblages; 
     public ObservableCollection<Assemblage> ListAssemblages 
     { 
      get { return listAssemblages; } 
      set 
      { 
       listAssemblages = value; 
       if (PropertyChanged != null) 
       { 
        NotifyPropertyChanged("ListAssemblages"); 
       } 
      } 
     } 
    ... 
    } 

1)契約書(ListView1)をダブルクリックすると、その相のListView2リストで、私は次のようにします。私は私のフェーズを編集する場合

contexte.SelectedAffaire = (Affaire)ListView1.SelectedItem; 
contexte.SelectedAffaire.getListPhases(); 
afficherListview("2"); 

2)、すべてが)私の見解であり、また私のObservableCollection

3に正しく更新されて追加/削除のために新しい段階、すべてが解決されます。

編集:Netstepで与え

例は完璧に動作しますが、私はまだ問題を満たす:

私は第3レベル「アセンブリ」を持っている、これはクラス「フェーズ」でのObservableCollectionで、私が持っています4つのリストビューでナビゲートするのに問題はありませんが、何か他のものを作成したいときに問題が発生します。「フェーズ」のヘッダを右クリックすると、アセンブリのリスト、すべてのアセンブリのリストフェーズでフィルタリングせずに、Affaireに含まれています。私は次のようにします。このため :私は右のフェーズヘッダやイベントをクリックして作る、第3レベルのリストビューアセンブリの午前には、以下の通りである:

Phase ph = new Phase(); 
       ph.IdAffaire = contexte.SelectedAffaire.ID; 
       ph.ListAssemblages = new ObservableCollection<Assemblage>(contexte.SelectedAffaire.getListAssemblages(true)); 
       contexte.SelectedPhase = ph; 

I「たわごと」だけで、新しい空の位相を作るビットObservableCollectionを内部に配置し、ObservableCollectionをListView3にバインドします。 編集:ここではコードの一部は、良い作品...私はちょうどどこかに私のコードのコンテキストをリフレッシュし、それについて忘れてしまった、結着で何か問題があったことを確認してください...すべて解決おかげ

答えて

1

は一例ですあなたのソースに基づいて、すべてのものを処理します。 aビューモデル:

using System.Collections.ObjectModel; システムを使用しています。ComponentModel;

名前空間WpfApp2 {パブリッククラスBaseViewModel: {公開イベントPropertyChangedEventHandlerにPropertyChangedをINotifyPropertyChangedの。

public void NotifyPropertyChanged(string nomPropriete) 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(nomPropriete)); 
    } 
} 

public class Contexte : BaseViewModel 
{ 
    private Affaire _selectedAffaire; 
    private Phase _selectedPhase; 
    public ObservableCollection<Affaire> ListeDesAffaires { get; set; } 

    public Affaire SelectedAffaire 
    { 
     get { return _selectedAffaire; } 
     set 
     { 
      _selectedAffaire = value; 
      this.NotifyPropertyChanged("SelectedAffaire"); 
     } 
    } 

    public Phase SelectedPhase 
    { 
     get { return _selectedPhase; } 
     set 
     { 
      _selectedPhase = value; 
      this.NotifyPropertyChanged("SelectedPhase"); 
     } 
    } 

    public Contexte() 
    { 
     ListeDesAffaires = new ObservableCollection<Affaire> 
     { 
      new Affaire("Affaire1"), 
      new Affaire("Affaire2") 
     }; 
    } 
} 

public class Affaire : BaseViewModel 
{ 
    private string nom; 
    public string Nom 
    { 
     get { return this.nom; } 
     set 
     { 
      this.nom = value; 
      this.NotifyPropertyChanged("Nom"); 
     } 
    } 

    public ObservableCollection<Phase> ListPhases { get; set; } 

    public Affaire(string n) 
    { 
     nom = n; 
     ListPhases = new ObservableCollection<Phase> 
     { 
      new Phase { NomPhase = nom + "_Phase1" }, 
      new Phase { NomPhase = nom + "_Phase2" } 
     }; 
    } 
} 

public class Phase : BaseViewModel 
{ 
    private string nomPhase; 
    public string NomPhase 
    { 
     get { return this.nomPhase; } 
     set 
     { 
      this.nomPhase = value; 
      this.NotifyPropertyChanged("NomPhase"); 
     } 
    } 

    public ObservableCollection<Assemblage> ListAssemblages { get; set; } 
} 

public class Assemblage : BaseViewModel 
{ 
    private string nom; 
    public string Nom 
    { 
     get { return this.nom; } 
     set 
     { 
      this.nom = value; 
      this.NotifyPropertyChanged("Nom"); 
     } 
    } 

} 

}

MainWindow.xaml:

<Window x:Class="WpfApp2.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:local="clr-namespace:WpfApp2" 
     mc:Ignorable="d" 
     Title="MainWindow" Height="350" Width="525"> 
    <Window.DataContext> 
     <local:Contexte x:Name="Contexte" d:IsDataSource="True" /> 
    </Window.DataContext> 
    <Grid> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="1*"/> 
      <ColumnDefinition Width="1*"/> 
      <ColumnDefinition Width="1*"/> 
     </Grid.ColumnDefinitions> 
     <ListBox ItemsSource="{Binding ListeDesAffaires}" DisplayMemberPath="Nom" SelectedItem="{Binding SelectedAffaire}"/> 
     <ListBox Grid.Column="1" ItemsSource="{Binding SelectedAffaire.ListPhases}" DisplayMemberPath="NomPhase" /> 
     <Button Grid.Column="2" VerticalAlignment="Top" Click="FillClick">Fill</Button> 
     <ListBox Grid.Column="2" ItemsSource="{Binding SelectedPhase.ListAssemblages}" DisplayMemberPath="Nom" Margin="0,20,0,0"/> 
    </Grid> 
</Window> 

そして、あなたの質問(MainWindow.xaml.cs)からいくつかのコード:

using System.Collections.ObjectModel; 
using System.Windows; 

namespace WpfApp2 
{ 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
     } 

     private void FillClick(object sender, RoutedEventArgs e) 
     { 
      Phase ph = new Phase(); 
      ph.NomPhase = "SomeId"; 
      ph.ListAssemblages = new ObservableCollection<Assemblage>() 
      { 
       new Assemblage { Nom = "Assemblage1" }, 
       new Assemblage { Nom = "Assemblage2" } 
      }; 
      Contexte.SelectedPhase = ph; 
     } 
    } 
} 

そして、ここではその結果であります:

Result

これは拡張可能な基本的なサンプルです。すべてのフィールドの変更とオブジェクトの追加と削除を行い、画面に表示します。 MainWindow.xaml.csには追加のコードはありません。質問があれば質問してください。

+0

ohoh ...完璧な回答ありがとう、SelectedItemにバインドできるかどうかわかりませんでした。私はフェーズを削除/追加するために、私はちょうどSelectedAffaire.ListeDesPhases.Add(MyPhase)、またはSelectedAffaire.ListeDesPhases.Remove(MyPhase)として何かする必要があると思いますか? ListViewAffaire.SelectedItem、ListViewSubPhase、ListViewPhase.SelectedItemなどのバインドでListViewPhaseバインドを使用してObservableCollectionを1つだけ使用します(実際には2つではなく4つのレベルになります) –

+0

すみません、私はまだ会います私のポストを編集して^^ ' –

+0

私は私の答えを編集し、同様のコードを実行するボタンを追加し、それはうまくいくでしょう。 – Netstep

関連する問題