2017-02-15 5 views
0

Ich habe eine Gruppe Klasse, die eine Liste von Elementen und einen Header enthält:Ausgewählte Artikel von Mehreren Listen

public class MyGroup {  
    public MyGroup(string _header){ 
     header = _header; 
    } 

    protected string header = ""; 
    public string Header 
    { 
     get { return header; } 
    } 

    protected List<MyGroupItem> item = new List<MyGroupItem>(); 
    public List<MyGroupItem> Item 
    { 
     get { return item; } 
    } 
} 

public class MyGroupItem {  
    public MyGroupItem(string _name, double _multiplier){ 
     name = _name; 
     multiplier = _multiplier; 
    } 

    protected double multiplier = 1.0; 

    protected string name = ""; 
    public string Name 
    { 
     get { return name; } 
    } 
} 

So weit so gut. In meinem Hauptklasse, ich habe eine beobachtbare Sammlung von Gruppen und ich füllen Sie es wie folgt aus:

protected ObservableCollection<MyGroup> groups = new ObservableCollection<MyGroup>(); 
public ObservableCollection<MyGroup> Groups 
{ 
    get { return groups; } 
} 

protected MyGroupItem currentItem; 
public MyGroupItem CurrentItem 
{ 
    get { return currentItem; } 
    set 
    { 
     if (currentItem== value) return; 
     currentItem= value; 
     NotifyPropertyChanged("CurrentItem"); 
    } 
} 

.... 

var GroupA = new MyGroup("Group A"); 
GroupA.MyGroupItem.Add("Item 1", 1.0); 
Groups.Add(GroupA); 

currentItem = GroupA.MyGroupItem[0]; 

Alle oben zeigt einfach, wie ich habe Setup meine Klassen und beobachtbaren Listen. Jetzt wechsle ich zum XAML.

<ItemsControl ItemsSource="{Binding Path=Groups}"> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <StackPanel Background="Transparent" ClipToBounds="True" Orientation="Vertical"></StackPanel> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 

    <ItemsControl.ItemTemplate> 
     <DataTemplate DataType="{x:Type local:MyGroup}"> 
      <StackPanel> 
       <TextBlock Text="{Binding Path=Header}"></TextBlock> 
       <ListView ItemsSource="{Binding Path=MyGroupItem}" SelectedItem="{Binding Path=DataContext.CurrentItem, ElementName=ControlRoot}"> 
        <ListView.ItemTemplate> 
         <DataTemplate DataType="local:MyGroupItem"> 
          <TextBlock Text="{Binding Path=Name}"></TextBlock> 
         </DataTemplate> 
        </ListView.ItemTemplate> 
       </ListView> 
      </StackPanel> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

Also, im Grunde habe ich ein ItemControl, das mehrere Listen von Elementen anzeigt. Das Steuerelement sollte die Kopfzeile für den Namen der Gruppe platzieren und dann eine Listenansicht der bestimmten Elemente in dieser Gruppe anzeigen. Das Layout funktioniert einwandfrei ... aber das Problem kommt, wenn ich mit dem Ausgewählten Artikel. Grundsätzlich erlaubt mir die Listenansicht, ein Element innerhalb einer der mehreren Gruppen auszuwählen. Das bedeutet, dass ich zu einem bestimmten Zeitpunkt mehrere Objekte ausgewählt haben kann. Nehmen wir zum Beispiel an, dass ich das erste Element in Gruppe A auswähle. Aber dann ändere ich meine Auswahl auf das zweite Element in Gruppe B. Da Gruppe B eine separate Liste ist, kann ich dieses Element aktivieren ... aber es Der Eintrag in Gruppe A wird nicht deaktiviert. Ich möchte, dass diese Gruppe mit mehreren Listen als eine einzige Liste fungiert. Ist das möglich? Muss ich ein separates SelectionChanged Event einrichten? Und wenn ja, wie würde ich sicherstellen, dass die Auswahl geändert wird, wenn die ausgewählten Elemente aus allen Listen gelöscht werden und nur die richtige Auswahl angezeigt wird, die der Benutzer gerade ausgewählt hat?

Antwort

1

Sie sollten dies in Ihren Ansichtsmodellklassen behandeln.

Wenn Sie eine Eigenschaft hinzufügen, um das ausgewählte Element jeder Gruppe in die MyGroup Klasse zu halten und implementieren, um die INotifyPropertyChanged Schnittstelle, man konnte das CollectionChanged Ereignis der Groups Sammlung in der View-Modell Klasse behandelt die CurrentItem Eigenschaft zu setzen und bei der Gleichzeitig löschen Sie die SelectedItem Eigenschaft der anderen Gruppen, indem Sie sie in diesem Ereignishandler auf null setzen.

Hier ist ein Beispiel für Sie.

MyGroup.cs:

public class MyGroup : INotifyPropertyChanged 
{ 
    public MyGroup(string _header) 
    { 
     header = _header; 
    } 

    protected string header = ""; 
    public string Header 
    { 
     get { return header; } 
    } 

    protected List<MyGroupItem> item = new List<MyGroupItem>(); 
    public List<MyGroupItem> Item 
    { 
     get { return item; } 
    } 

    private MyGroupItem _item; 
    public MyGroupItem SelectedItem 
    { 
     get { return _item; } 
     set { _item = value; NotifyPropertyChanged(); } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "") 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 

} 

MyGroupItem.cs:

public class MyGroupItem 
{ 
    public MyGroupItem(string _name, double _multiplier) 
    { 
     name = _name; 
     multiplier = _multiplier; 
    } 

    protected double multiplier = 1.0; 

    protected string name = ""; 
    public string Name 
    { 
     get { return name; } 
    } 
} 

Ansicht Modell:

public class Window1ViewModel : INotifyPropertyChanged 
{ 
    public Window1ViewModel() 
    { 
     groups.CollectionChanged += (s, e) => 
     { 
      if (e.NewItems != null) 
      { 
       foreach (object item in e.NewItems) 
       { 
        (item as INotifyPropertyChanged).PropertyChanged 
         += new PropertyChangedEventHandler(item_PropertyChanged); 
       } 
      } 

      if (e.OldItems != null) 
      { 
       foreach (object item in e.OldItems) 
       { 
        (item as INotifyPropertyChanged).PropertyChanged 
         -= new PropertyChangedEventHandler(item_PropertyChanged); 
       } 

      }; 
     }; 

     var GroupA = new MyGroup("Group A"); 
     GroupA.Item.Add(new MyGroupItem("Item 1", 1.0)); 
     GroupA.Item.Add(new MyGroupItem("Item 2", 1.0)); 
     GroupA.Item.Add(new MyGroupItem("Item 3", 1.0)); 
     Groups.Add(GroupA); 

     var GroupB = new MyGroup("Group B"); 
     GroupB.Item.Add(new MyGroupItem("Item 1", 1.0)); 
     GroupB.Item.Add(new MyGroupItem("Item 2", 1.0)); 
     GroupB.Item.Add(new MyGroupItem("Item 3", 1.0)); 
     Groups.Add(GroupB); 

     currentItem = GroupA.Item[0]; 
    } 

    private bool _handle = true; 
    private void item_PropertyChanged(object sender, PropertyChangedEventArgs e) 
    { 
     if (!_handle) 
      return; 

     MyGroup group = sender as MyGroup; 
     CurrentItem = group.SelectedItem; 

     //clear the selection in the other groups: 
     _handle = false; 
     foreach (MyGroup g in Groups) 
      if (g != group) 
       g.SelectedItem = null; 
     _handle = true; 
    } 

    protected ObservableCollection<MyGroup> groups = new ObservableCollection<MyGroup>(); 
    public ObservableCollection<MyGroup> Groups 
    { 
     get { return groups; } 
    } 

    protected MyGroupItem currentItem; 
    public MyGroupItem CurrentItem 
    { 
     get { return currentItem; } 
     set 
     { 
      if (currentItem == value) return; 
      currentItem = value; 
      NotifyPropertyChanged("CurrentItem"); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "") 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

Anzeigen:

<ItemsControl ItemsSource="{Binding Path=Groups}"> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <StackPanel Background="Transparent" ClipToBounds="True" Orientation="Vertical"></StackPanel> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate DataType="{x:Type local:MyGroup}"> 
      <StackPanel> 
       <TextBlock Text="{Binding Path=Header}"></TextBlock> 
       <ListView ItemsSource="{Binding Path=Item}" 
            SelectedItem="{Binding SelectedItem}"> 
        <ListView.ItemTemplate> 
         <DataTemplate DataType="local:MyGroupItem"> 
          <TextBlock Text="{Binding Path=Name}"></TextBlock> 
         </DataTemplate> 
        </ListView.ItemTemplate> 
       </ListView> 
      </StackPanel> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 
+0

Dies funktionierte perfekt! Danke für die gründliche Antwort! – andyopayne

Verwandte Themen