简体   繁体   中英

WPF MVVM Binding visibility to dynamic MenuItem

How to update Context MenuItem when Commands CanExecute* method change it's state.

I have a problem regarding binding visibility to dynamicaly created MenuItems (based on ICommands and DataTemplates ). ContextMenu is created for GridControl which binds some custom parameters. I managed to bind those parameters via Freezable proxy to ContextMenu . All works allmost OK, except CanExecute* does not change MenuItem visbility. If CanExecute* have constant e.CanExecute = true , than it's OK (menuitem is active), but when CanExecute* have some logic and can have both states, than MenuItem always have IsEnabled set to false

Some code:
ContextCommands is extension of ICommand

IEnumerable<ICommand<SomeClass>> ContextCommands

CustomMenuItem

//CustomMenuItem is just extension of MenuItem  
public class CustomMenuItem : MenuItem

DataTemplates

<DataTemplate DataType="{x:Type....
<controls:CustomMenuItem Command="{Binding Path=WrappedCommand}" Visibility="{Binding Path=IsVisible, Converter={StaticResource VisibilityConverter}}">
<commandparameters ... (parameters works OK, so i skip that)>

Grid Declaration

<controls:CustomGridControl Grid.Row="1" x:Name="MyGrid"
                                   ColumnDescriptions="{Binding Source.ColumnDescriptions}" 
                                   QueryableSource="{Binding Source.Query}"
                                   Tag="{Binding DataContext, RelativeSource={RelativeSource Mode=Self}}"
                                    >
    <controls:CustomGridControl.Resources>
        <helpers:BindingProxyHelper x:Key="DataProxy" Data="{Binding ElementName=MyGrid, Path=., Mode=TwoWay}" />
    </controls:CustomGridControl.Resources>
    <controls:CustomGridControl.ContextMenu>
        <contextmenu:CustomContextMenu 
            DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}"
            ItemsSource="{Binding ContextCommands}"
            BindableProperties="{Binding Data, Source={StaticResource DataProxy}, Mode=TwoWay}">
        </contextmenu:CustomContextMenu>
    </controls:CustomGridControl.ContextMenu>
</controls:CustomGridControl>

How to invoke Visibility to dynamic MenuItem when CanExecute changes? I tried to pass DataContext but that has no effect, UI does not changes Debuging this binding shows that Visibility is correctly set, but without effect.

CAN EDIT FALSE
System.Windows.Data Warning: 56 : Created BindingExpression (hash=2852357) for Binding (hash=35737921)
System.Windows.Data Warning: 58 :   Path: 'IsVisible'
System.Windows.Data Warning: 60 : BindingExpression (hash=2852357): Default mode resolved to OneWay
System.Windows.Data Warning: 61 : BindingExpression (hash=2852357): Default update trigger resolved to PropertyChanged
System.Windows.Data Warning: 62 : BindingExpression (hash=2852357): Attach to Controls.CustomMenuItem.Visibility (hash=36410781)
System.Windows.Data Warning: 67 : BindingExpression (hash=2852357): Resolving source 
System.Windows.Data Warning: 70 : BindingExpression (hash=2852357): Found data context element: CustomMenuItem (hash=36410781) (OK)
System.Windows.Data Warning: 78 : BindingExpression (hash=2852357): Activate with root item CommandWithParameterPlugin`1 (hash=19041329)
System.Windows.Data Warning: 108 : BindingExpression (hash=2852357):   At level 0 - for CommandWithParameterPlugin`1.IsVisible found accessor ReflectPropertyDescriptor(IsVisible)
System.Windows.Data Warning: 104 : BindingExpression (hash=2852357): Replace item at level 0 with CommandWithParameterPlugin`1 (hash=19041329), using accessor ReflectPropertyDescriptor(IsVisible)
System.Windows.Data Warning: 101 : BindingExpression (hash=2852357): GetValue at level 0 from CommandWithParameterPlugin`1 (hash=19041329) using ReflectPropertyDescriptor(IsVisible): 'True'
System.Windows.Data Warning: 80 : BindingExpression (hash=2852357): TransferValue - got raw value 'True'
System.Windows.Data Warning: 82 : BindingExpression (hash=2852357): TransferValue - user's converter produced 'Visible'
System.Windows.Data Warning: 89 : BindingExpression (hash=2852357): TransferValue - using final value 'Visible'
CAN EDIT TRUE
CAN EDIT TRUE

I've looked in stackoverflow for answers, found a lot of suggestions, but still no luck with my problem.

I assume problem might be with assingning Binding ContextCommands to CustomContextMenu, since it may be outside of the visualtree. Solution probably might be some kind of proxy for that, but i have no idea how to implement it.

To resolve problem with accessing menuItem visibility through command and binding command and parameters was to set data templates in MenuItem style Since there is multiple command types in project selection is made through TypeNameConverter

<Style.Triggers>
    <DataTrigger Binding="{Binding Converter={StaticResource TypeNameConverter}}" Value="CommandType`1">
        <Setter Property="CommandParameter" Value="{Binding SomeParametersFromParent, RelativeSource={RelativeSource AncestorType={x:Type local:CustomContextMenu}}}"/>
        <Setter Property="Command" Value="{Binding Path=Command}"/>
        <Setter Property="Header" Value="{Binding Path=HeaderInfo}"/>
    </DataTrigger>

Hope this helps some of you with similar problem

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM