Frage

Ive dies ein paar Mal bemerkt, wenn sie mit Befehlen Menüs, sind sie nicht sehr dynamisch, überprüfen Sie diese aus. Ich bin ein Menü aus einer Sammlung von Farben zu schaffen, verwende ich es eine Spalte in einem Datagrid zu färben. Wie auch immer, wenn ich zum ersten Mal das Menü (es ist ein Kontextmenü) das Kommando Parameterbindung geschieht bringen und es bindet an die Säule, dass das Kontextmenü geöffnet wurde auf. Doch das nächste Mal, wenn ich es bringe es scheint wpf die Menü-Caches und es tut den Befehl Parameter erneut binden. so dass ich die Farbe nur auf der Anfangsspalte festlegen, dass das Kontextmenü erscheint auf.

Ich habe um diese Situation in der Vergangenheit bekam, indem sie das Menü vollständig dynamisch und zerstören die Sammlung, wenn das Menü geschlossen und zwingt eine das nächste Mal wieder aufzubauen geöffnet, ich dont wie dieser Hack. Hat jemand einen besseren Weg?

    <MenuItem
       Header="Colour"
       ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:ResultEditorGrid}}, Path=ColumnColourCollection}"
       ItemTemplate="{StaticResource colourHeader}" >
       <MenuItem.Icon>
          <Image
             Source="{StaticResource ColumnShowIcon16}" />
       </MenuItem.Icon>
       <MenuItem.ItemContainerStyle>
          <Style
             TargetType="MenuItem"
             BasedOn="{StaticResource systemMenuItemStyle}">
             <!--Warning dont change the order of the following two setters
                                otherwise the command parameter gets set after the command fires,
                                not mush use eh?-->
             <Setter
                Property="CommandParameter">
                <Setter.Value>
                   <MultiBinding>
                      <MultiBinding.Converter>
                         <local:ColumnAndColourMultiConverter/>
                      </MultiBinding.Converter>
                      <Binding RelativeSource="{RelativeSource AncestorType={x:Type DataGridColumnHeader}}" Path="Column"/>
                      <Binding Path="."/>
                   </MultiBinding>
                </Setter.Value>
             </Setter>
             <Setter
                Property="Command"
                Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:ResultEditorGrid}}, Path=ColourColumnCommand}" />
          </Style>
       </MenuItem.ItemContainerStyle>
    </MenuItem>
War es hilfreich?

Lösung

Das Problem ist, dass ContextMenu die sind offenbar die Wurzel ihrer eigenen visuellen Struktur ich irgendwo gelesen, dass es die Datacontext nimmt seinen Eltern, aber nur einmal beim Laden, so dass, wenn die Eltern die Datacontext menuitems ändert sich nicht. (Leider kann ich keinen Link für das finden Recht nicht)

Ich habe dieses Problem vor, und was ich tat, war die Verwendung Virtual Zweig Muster Josh Smith. Es ist ziemlich technisch, aber der Artikel hat mir geholfen wirklich gut verstehen, was mit diesem visuellen Baum Unsinn vorging.

Im Wesentlichen erstellen Sie diese Brücke, dass bindet an die Datacontext Sicht. Die Brücke wird erstellt als statische Ressource , so dass Sie es aus dem Kontextmenü zu binden, auch wenn sie außerhalb der visuellen Struktur ist.

Fügen Sie diese auf Ihre XAML:

<Window.Resources>
   <!-- This is the "root node" in the virtual branch
   attached to the logical tree. It has its
   DataContext set by the Binding applied to the
   Window's DataContext property. -->
   <FrameworkElement x:Key="DataContextBridge" />
</Window.Resources>

<Window.DataContext>
   <!-- This Binding sets the DataContext on the "root node"
   of the virtual logical tree branch.  This Binding
   must be applied to the DataContext of the element
   which is actually assigned the data context value. -->
   <Binding
    Mode="OneWayToSource"
    Path="DataContext"
    Source="{StaticResource DataContextBridge}"
   />
</Window.DataContext>

Dies ist die Brücke, die ich gesprochen hat. Es nimmt die Datacontext und __pushes it_ bis zu den Brücken Datacontext, die (wie gesagt) eine statische Ressource.

Sie dann einfach diese auf die contextmenu Datacontext:

 DataContext="{Binding
               Source={StaticResource DataContextBridge},
               Path=DataContext}"

werfen nun alle relativ Wegfindung usw. entfernt und regelmäßige Verwendung innerhalb der Menüpunkte zu binden, und Sie sollten in Ordnung sein. Die Datacontext wird wie gewohnt aktualisieren.

Nur eine Anmerkung:

Sie werden natürlich eine Eigenschaft in der Datacontext haben müssen, zu erkennen, welchen Befehl zu verwenden, aber ich bin sicher, können Sie es herausfinden. Diese Lösung nur befasst sich mit dem Update tun sie nicht die Art und Weise contextmenu

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top