Pregunta

He notado esto un par de veces en que el uso de menús con comandos, que no son muy dinámicos, mira esto. Estoy creando un menú de una colección de colores, lo uso para dar color a una columna en una cuadrícula de datos. De todos modos lo primero, cuando aparezca el menú (es un menú de contexto) que se une el parámetro del comando pasa y se une a la columna que el menú contextual se abrió el. Sin embargo, la próxima vez que llevarlo hasta parece WPF caja de menú y es imposible volver a vincular el parámetro del comando. para que pueda establecer el color sólo en la columna inicial de que el menú de contexto apareció en.

Me han llegado en torno a esta situación en el pasado por lo que el menú totalmente dinámica y la destrucción de la colección cuando el menú cerrado y obligando a una reconstrucción que la próxima vez que se abrió, no me gusta este corte. Alguien tiene una mejor manera?

    <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>
¿Fue útil?

Solución

El problema es que son de ContextMenu parecer, la raíz de su propio árbol visual leí en alguna parte que toma la DataContext su padres, pero sólo una vez en la carga, por lo que si los padres DataContext cambia el menuitems no lo hace. (Por desgracia no puedo encontrar un vínculo de ese derecho no)

he encontrado con este problema antes, y lo que hice fue el uso de Josh Smith virtual patrón Branch . Es bastante técnico pero el artículo me ayudó a entender muy bien lo que estaba pasando con este absurdo árbol visual.

En esencia, se crea este puente que une a DataContext de la vista. Se crea el puente como un recurso estático , lo que le permite obligar a la misma desde el menú contextual, incluso si se encuentra fuera del árbol visual.

Añadir esto a su 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>

Este es el puente que hablé. Toma el DataContext y it_ __pushes a a los puentes DataContext, que es (como dije antes) un recurso estático.

A continuación, simplemente esto a DataContext del menú contextual:

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

Ahora tirar todo el encauzamiento etc relativa y el uso regular de unión dentro de los elementos de menú, y usted debe estar bien. El DataContext se actualizará como de costumbre.

Sólo una nota:

Usted, evidentemente, tiene que tener alguna propiedad en el DataContext de discernir cuál de comandos para su uso, pero estoy seguro de que puedes averiguarlo. Esta solución solo se ocupa de la actualización no haga la forma de menú contextual

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top