2016-10-10 3 views
2

ZusammenfassungNicht in der Lage Daten in Dropdownbutton zu organisieren

Ich habe ein DropDownButton, die alle Ligen einer bestimmten Nation enthält. Im Wesentlichen wählt der Benutzer eine Nation aus einer ComboBox und die Leagues der ausgewählten Nation wird innerhalb der DropDownButton hinzugefügt. Bis hier kein Problem.

Was ich tun muss, ist: organisieren Sie die Leagues innerhalb der DropDownButton für Nation. So vorstellen, dass im Inneren des DropDownButton habe ich diese Organisation:

Italy 
    Item1 
    Item2 
    Item3 
England 
    Item1 
    Item2 
Spain 
    Item1 
    Item2 
... etc ... 

Einzelteilart

Wie Sie das Element sehen können, werden durch Nation organisiert. Bevor ich erkläre, was ich getan habe, um dieses Ergebnis zu erreichen, muss ich sagen, dass ich eine CheckedListItem Klasse verwende, die im Wesentlichen eine Klasse ist, die ein CheckBox an das Element der DropDownButton bindet. Diese Klasse ist ziemlich einfach:

public class CheckedListItem<T> : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    private bool isChecked; 
    private T item; 

    public CheckedListItem() { } 

    public CheckedListItem(T item, bool isChecked = false) 
    { 
     this.item = item; 
     this.isChecked = isChecked; 
    } 

    public T Item 
    { 
     get { return item; } 
     set 
     { 
      item = value; 
      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Item")); 
     } 
    } 

    public bool IsChecked 
    { 
     get { return isChecked; } 
     set 
     { 
      isChecked = value; 
      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("IsChecked")); 
     } 
    } 
} 

Im Wesentlichen zur Verfügung zu stellen, die Item<T> und wenn ausgewählt. Für stellen diese Arbeiten in XAML schrieb ich diesen Code in den Window.Resources:

<DataTemplate x:Key="NormalItemTemplate"> 
    <CheckBox IsChecked="{Binding IsChecked}" Content="{Binding Item.Name}" 
       x:Name="Leagues" Checked="Leagues_Checked" Unchecked="Leagues_Unchecked" /> 
</DataTemplate> 

<DataTemplate x:Key="SelectionBoxTemplate" > 
    <TextBlock Text="{DynamicResource displayedNation}"/> 
</DataTemplate> 

<DataTemplate x:Key="CombinedTemplate"> 
    <ContentPresenter x:Name="Presenter" Content="{Binding}" ContentTemplate="{StaticResource NormalItemTemplate}" /> 
    <DataTemplate.Triggers> 
     <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, Controls:DropDownButton, 1}}" 
        Value="{x:Null}"> 
      <Setter TargetName="Presenter" Property="ContentTemplate" 
        Value="{StaticResource SelectionBoxTemplate}" /> 
     </DataTrigger> 
    </DataTemplate.Triggers> 
</DataTemplate> 

<!--This is for the group item !--> 

<Style TargetType="{x:Type GroupItem}" x:Key="containerStyle"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type GroupItem}"> 
       <!--Here, we tell that each group of item will be placed under Expander control, 
        and this expander control will by default will have style we defined in above code.--> 
       <Expander IsExpanded="False" x:Name="ComboExpander" Header="{TemplateBinding Content}" 
          HeaderTemplate="{TemplateBinding ContentTemplate}"> 
        <ItemsPresenter /> 
       </Expander> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

Erklären Sie das Problem

Jetzt für die Gruppierung erreicht in den DropDownButton ich ein CollectionViewSource im Window.Resource wie diese ersten erstellt habe :

<CollectionViewSource Source="{Binding Leagues}" x:Key="GroupedData"> 
    <CollectionViewSource.GroupDescriptions> 
     <PropertyGroupDescription PropertyName="Item.Country" /> 
    </CollectionViewSource.GroupDescriptions> 
</CollectionViewSource> 

<DataTemplate x:Key="GroupHeader"> 
    <TextBlock Text="{Binding Name}" Margin="10,0,0,0" Foreground="#989791"/> 
</DataTemplate> 

im DropDownButton stelle ich diese Struktur:

<Controls:DropDownButton Content="Leagues" x:Name="LeagueMenu" 
          ItemsSource="{Binding Source={StaticResource GroupedData}}" 
          ItemTemplate="{StaticResource CombinedTemplate}" > 
    <Controls:DropDownButton.GroupStyle> 
     <GroupStyle ContainerStyle="{StaticResource containerStyle}" 
        HeaderTemplate="{StaticResource GroupHeader}"> 
     </GroupStyle> 
    </Controls:DropDownButton.GroupStyle> 
</Controls:DropDownButton> 

(Bitte beachten Sie, dass ich mit MahApp)

So im Wesentlichen habe ich eine Vorlage für die CheckedListItem und als ItemSource die GroupedData, dass, wie Sie die ObservableCollection von Leagues von Code oben binden sehen .

Daten Bevölkerung

Wenn ein Nation eine Liste von Leagues für die gewählten Nations gewählt ist, wird in den DropDownButton hinzugefügt werden, für den Code dieses Ziel zu erreichen:

private ObservableCollection<CheckedListItem<League>> _leagues = new ObservableCollection<CheckedListItem<League>>(); 
public ObservableCollection<CheckedListItem<League>> Leagues 
{ 
    get 
    { 
     return _leagues; 
    } 
    set 
    { 
     _leagues = value; 
     OnPropertyChanged(); 
    } 
} 

die Methode, die aufgerufen werden für fügen Sie die League der ausgewählten Nation ist dies:

public void GetLeagues(string link, string nation) 
{ 
    Task.Run(() => 
    { 
     var leagues = //get some collection 

     foreach (var league in leagues) 
     { 
      var championship = new CheckedListItem<League>(); 
      championship.Item = new League { Name = league.Name, Link = league.Link, Country = nation }; 
      _leagues.Add(championship); 
     } 
    }); 
} 

Im Wesentlichen erstelle ich ein CheckedListItem von League, die diese Eigenschaft als Modell enthält:

public class League 
{ 
    public string Name { get; set; } 
    public string Link { get; set; } 
    public string Country { get; set; } 
} 

Das Ergebnis, das in etwa so erscheinen werden soll, ist:

enter image description here

from this tutorial genommen.

Aber stattdessen bekomme ich dieses Ergebnis:

enter image description here

Wie man sehen kann ich nicht den Header mit dem Namen Nation Gruppierung hat. Ich bekomme auch keinen Fehler in XAML oder im Code, deshalb weiß ich nicht, warum der Header nicht erscheint.

Ich weiß, dass das Problem ein wenig kompliziert sein könnte, so für jede Frage oder weitere Details fragen Sie mich und ich werde versuchen, zu beantworten.

Demo Lösung:

https://mega.nz/#!g4YlTL4A!G4WXy1t64Q4yImYNvzgwGbieX1mhKnXO2OiuAO3FDg0

+0

Ich habe MahApp nicht hier, aber was ich normalerweise in Situationen wie diesen mache, ist das Hinzufügen verschiedener Hintergrundfarben zu verschiedenen Elementen. Das macht es einfacher zu sehen, welche Vorlagen und Elemente angezeigt werden. –

+0

@PieterWitvoet Das Problem ist auf 'combinedTemplate', das in der Gruppierung nicht funktioniert. – AgainMe

+0

Scheint wie ein Duplikat von [dieser Frage] (http://stackoverflow.com/questions/39943204/organize-items-in-dropdownbutton/39967087). – Grx70

Antwort

4

Anstatt zu versuchen, die Kontrolle durch Dritte zur Arbeit zu kommen, würde ich ändern, die ComboBox Arbeit an Ihre Bedürfnisse anpassen:

Champ

MainWindow.xaml

<Controls:MetroWindow x:Class="WpfApplication1.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:Controls="http://metro.mahapps.com/winfx/xaml/controls" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:local="clr-namespace:WpfApplication1" 
     mc:Ignorable="d" 
     Title="MainWindow" Height="700" Width="525"> 
    <Window.Resources> 
     <ResourceDictionary> 

      <CollectionViewSource Source="{Binding Leagues}" x:Key="GroupedData"> 
       <CollectionViewSource.GroupDescriptions> 
        <PropertyGroupDescription PropertyName="Item.Country" /> 
       </CollectionViewSource.GroupDescriptions> 
      </CollectionViewSource> 

      <DataTemplate x:Key="GroupHeader"> 
       <TextBlock Text="{Binding Name}" Margin="10,0,0,0" Foreground="#989791"/> 
      </DataTemplate> 

      <Style TargetType="{x:Type GroupItem}" x:Key="containerStyle"> 
       <Setter Property="Template"> 
        <Setter.Value> 
         <ControlTemplate TargetType="{x:Type GroupItem}"> 
          <Expander IsExpanded="False" x:Name="ComboExpander" Header="{TemplateBinding Content}" 
             HeaderTemplate="{StaticResource GroupHeader}"> 
           <ItemsPresenter /> 
          </Expander> 
         </ControlTemplate> 
        </Setter.Value> 
       </Setter> 
      </Style> 

      <DataTemplate x:Key="NormalItemTemplate"> 
       <CheckBox IsChecked="{Binding IsChecked}" Content="{Binding Item.Name}" x:Name="Leagues" /> 
      </DataTemplate> 
      <DataTemplate x:Key="HeaderTemplate"> 
       <TextBlock Text="Campionati"/> 
      </DataTemplate> 
      <DataTemplate x:Key="CombinedTemplate"> 
       <ContentPresenter x:Name="Presenter" 
        Content="{Binding}" 
        ContentTemplate="{StaticResource NormalItemTemplate}" /> 
       <DataTemplate.Triggers> 
        <DataTrigger 
         Binding="{Binding RelativeSource={RelativeSource FindAncestor, ComboBoxItem, 1}}" 
         Value="{x:Null}"> 
         <Setter TargetName="Presenter" Property="ContentTemplate" 
          Value="{StaticResource HeaderTemplate}" /> 
        </DataTrigger> 
       </DataTemplate.Triggers> 
      </DataTemplate> 
     </ResourceDictionary> 

    </Window.Resources>  
    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition/> 
      <RowDefinition/> 
      <RowDefinition/> 
      <RowDefinition/> 
     </Grid.RowDefinitions> 
     <ComboBox x:Name="LeagueMenuComboBox" 
        ItemsSource="{Binding Source={StaticResource GroupedData}}" 
        ItemTemplate="{StaticResource CombinedTemplate}" 
        HorizontalContentAlignment="Center"> 
      <ComboBox.GroupStyle> 
       <GroupStyle ContainerStyle="{StaticResource containerStyle}" 
          HeaderTemplate="{StaticResource GroupHeader}"> 
       </GroupStyle> 
      </ComboBox.GroupStyle> 
     </ComboBox> 
    </Grid> 
</Controls:MetroWindow> 
+0

Vielen Dank für die Zeit, die Sie gewidmet haben. Ich habe ein paar Fragen, bevor ich deine Antwort akzeptiere: 1. Ist es möglich, einen Standardtext in der Combobox unabhängig vom ausgewählten Element zu setzen? 2. Ist es möglich, die Farbe des GroupBox-Textes zu ändern (ich meine die Landesnamenfarbe)? Vielen Dank. – AgainMe

+0

@AgainMe Gerne beantworten wir Ihre Fragen: 1. Dafür ist das 'CombinedTemplate' zuständig, es stellt sicher, dass der Standardtext immer gleich bleibt. 2. Sie können blaue Ländernamen erhalten, die den 'GroupHeader'-Inhalt setzen auf:' ' – Funk

+0

Danke, ich müssen stayoverflow Zeitlimit warten, um Ihnen das Kopfgeld zu senden. Nur eines: Ich bekomme leider keinen Standardtext in der Combobox angezeigt. – AgainMe