WPF: пункты меню только прикрепляют параметры команды один раз

StackOverflow https://stackoverflow.com/questions/3011184

Вопрос

Я заметил пару раз, когда используете меню с командами, они не очень динамичны, проверьте это. Я создаю меню из коллекции цветов, я использую его для цвета колонны в DataGrid. В любом случае, когда я впервые поднимаю меню (его контекстное меню), привязка параметра команд происходит, и он связывается с столбцом, на котором был открыт контекстное меню. Однако в следующий раз я приведу его, кажется, что 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>
Это было полезно?

Решение

Проблема в том, что контекстмен Видимо корень их собственного визуального дерева Я читал где-то, что требуется NataContext его родитель, но только один раз на загрузку, поэтому, если родители DataContext меняют меню. (К сожалению, я не могу найти ссылку для этого права не)

Я столкнулся с этой проблемой раньше, а что я сделал, было использовать Виртуальный филиал Джоша Смита. Отказ Это довольно техническое, но статья помогла мне действительно хорошо понять, что происходит с этим визуальным деревом ерунды.

По сути, вы создаете этот мост, который связывается с DataContext представления. Мост создан как статический ресурс, позволяя вам связывать с ним из контекстного меню, даже если он находится за пределами визуального дерева.

Добавьте это на свой 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 и __Pushes IT_ к мостам DataContext, который (как я уже сказал) статический ресурс.

Тогда вы просто это к DataContext ContextMenu:

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

Теперь выбросьте весь относительный путь и т. Д. и использовать регулярное связывание внутри пунктов меню, и вы должны быть в порядке. DataContext будет обновляться как обычно.

Только одна заметка:

Вы, очевидно, должны иметь некоторое свойство в DataContext, чтобы различить, какую команду использовать, но я уверен, что вы можете понять это. Это решение просто имеет дело с возможностью обновления ContextMenu

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top