3

コマンドでメニューを使用しているときに、これに数回気づきました。これらはあまり動的ではありません。これを確認してください。色のコレクションからメニューを作成しています。それを使用してデータグリッドの列に色を付けています。とにかく、最初にメニュー(コンテキストメニュー)を表示すると、コマンドパラメーターのバインドが発生し、コンテキストメニューが開かれた列にバインドされます。ただし、次回起動すると、wpfがメニューをキャッシュしているようで、コマンドパラメーターを再バインドしません。そのため、コンテキストメニューが表示された最初の列にのみ色を設定できます。

メニューを完全に動的にして、メニューを閉じたときにコレクションを破棄し、次に開いたときに強制的に再構築することで、過去にこの状況を回避しました。このハックは好きではありません。誰かがより良い方法を得ましたか?

    <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>
4

1 に答える 1

1

問題は、ContextMenuが明らかに独自のビジュアルツリーのルートであり、データコンテキストをその親として取得することをどこかで読んだことですが、ロード時に1回だけであるため、親のデータコンテキストが変更されてもmenuitemsは変更されません。(残念ながら、その権利へのリンクは見つかりません)

私は以前にこの問題に遭遇しました、そして私がしたことはJoshSmithの仮想ブランチパターンを使用することでした。かなり技術的ですが、この記事は、このビジュアルツリーのナンセンスで何が起こっているのかを非常によく理解するのに役立ちました。

基本的に、ビューのデータコンテキストにバインドするこのブリッジを作成します。ブリッジは静的リソースとして作成されるため、ビジュアルツリーの外部にある場合でも、コンテキストメニューからブリッジにバインドできます。

これを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>

これは私が話した橋です。datacontextを取得し、(前に述べたように)静的リソースであるbridgesdatacontextに__プッシュします_。

次に、これをコンテキストメニューのデータコンテキストに単純に追加します。

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

ここで、すべての相対パスなどを破棄し、メニュー項目内で通常のバインディングを使用します。これで問題ありません。datacontextは通常どおり更新されます。

注:

使用するコマンドを識別するには、明らかにdatacontextにいくつかのプロパティが必要ですが、それを理解できると確信しています。このソリューションは、コンテキストメニューが更新されない方法を処理するだけです

于 2012-03-19T11:47:44.687 に答える