2017-12-21 5 views
0

Ich lerne WPF und entwickle ein dynamisches Menü, das von der Datenbindung seiner ItemsSource an eine ObservableCollection gesteuert wird. Um dies zu tun habe ich eine einfache MenuItemViewModel und eine HierarchicalDataTemplate für die automatische Bindung von MenuItems zu ihm.Befehlsbindung an Menüeinträge der obersten Ebene funktioniert nicht

Das Problem, das ich habe, ist, dass Command Eigenschaft nicht für Top-Level-Menüelemente funktioniert. Obwohl es gesetzt ist, reagiert ein MenuItem nicht auf einen Mausklick und wird nicht deaktiviert, wenn der Befehl nicht ausgeführt werden kann. Es ist einfach so, als ob es nicht gebunden wird.

Für untergeordnete Menüelemente funktioniert es jedoch wie vorgesehen. Ich denke, das sollte ein Problem meiner HierarchicalDataTemplate sein, aber ich kann es nicht finden, denn wie ich sehe, gibt es keinen Code in der Vorlage, der die Befehlsbindung von nur MenuItems der obersten Ebene beeinflussen könnte.

MenuItemViewModel implementiert INotifyPropertyChanged und enthält folgende öffentliche Eigenschaften:

string Text 
Uri ImageSource 
ICommand Command 
ObservableCollection<MenuItemViewModel> Children 

HierarchicalDataTemplate für MenuItem in meinem Window.Resources ist wie folgt:

<HierarchicalDataTemplate DataType="{x:Type common:MenuItemViewModel}" 
          ItemsSource="{Binding Path=Children}"> 

    <HierarchicalDataTemplate.ItemContainerStyle> 
     <Style TargetType="MenuItem"> 
      <Setter Property="Command" 
       Value="{Binding Command}" /> 
     </Style> 
    </HierarchicalDataTemplate.ItemContainerStyle> 

    <StackPanel Orientation="Horizontal"> 
     <Image Source="{Binding ImageSource}" /> 
     <TextBlock Text="{Binding Text}" VerticalAlignment="Center"/> 
    </StackPanel> 

</HierarchicalDataTemplate> 

Können Sie mir bitte auf meinen Fehler hinweisen?

EDIT: Oberste Ebene MenuItem enthält keine Kinder (d. H. Children Sammlung von zugeordneten ViewModel ist leer).

+1

Ich denke, Sie sollten auch Code für ItemContainerStyle Ihres ItemControl oder etwas ähnliches schreiben. Ich bin mir nicht sicher, aber wenn Sie HierarchicalDataTemplate.ItemContainerStyle implementieren, gilt dies nur für ein beliebiges MenuItem in Ihren Containern. Ich meine, warum sollte dein Stil auf die erste Ebene angewendet werden, wenn du sagst: Zu jedem Element vom Typ menuItem, das in menuItem (container) sein wird, füge einen benutzerdefinierten Stil hinzu. – sTrenat

+0

@sTrenat so, wie es funktioniert ... Du hast die richtigen Gedanken angestupst. Vielen Dank! – 1valdis

Antwort

0

Dank @sTrenat comment bin ich zur Lösung unten gekommen.

<Menu.Resources> 
    <!-- cancel sharing of image so Icon will work properly --> 
    <Image x:Key="MenuIcon" Source="{Binding ImageSource}" x:Shared="False"/> 
</Menu.Resources> 

<Menu.ItemContainerStyle> 
    <Style TargetType="{x:Type MenuItem}" 
      BasedOn="{StaticResource {x:Type MenuItem}}"> 
     <Setter Property="Header" Value="{Binding Text}" /> 
     <Setter Property="Icon" Value="{StaticResource MenuIcon}"/> 
     <Setter Property="Command" Value="{Binding Command}"/> 
     <Setter Property="ItemsSource" Value="{Binding Children}" /> 

     <!-- centering MenuItem's Header --> 
     <Setter Property="HeaderTemplate"> 
      <Setter.Value> 
       <DataTemplate> 
        <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Content="{Binding}" /> 
       </DataTemplate> 
      </Setter.Value> 
     </Setter> 

     <!-- setting Icon to null when ImageSource isn't specified --> 
     <Style.Triggers> 
      <DataTrigger Binding="{Binding ImageSource}" 
         Value="{x:Null}"> 
       <Setter Property="Icon" Value="{x:Null}"/> 
      </DataTrigger> 
     </Style.Triggers> 
    </Style> 
</Menu.ItemContainerStyle> 
Verwandte Themen