Reputation: 1442
I have a context menu and at certain point i disable some of the commands bound to context menu items.
what works:
when the command gets disabled , clicking on the menu item does not call the execute method on the command as i wanted.
What does not work:
Both commands that can exucute and those which cant look identical!! my users cant tell the difference.
Problem:
How can I change the style to display this change. Change in background color, border color, foreground color , a tooltip... anything will be acceptable..
I experimented with xaml and was unable to solve this. (I am a noob with xaml so my attempts are not even worth pasting here :) )
xaml :
<Border BorderThickness="1" MinWidth="100" Background="Transparent" ContextMenu="{Binding Path=ContextMenu}" BorderBrush="{Binding Path=BorderColor}">
Binding:
public override ContextMenu ContextMenu
{
get
{
return new ContextMenu
{
ItemsSource = new ObservableCollection<MenuItem>
{
new MenuItem
{
Header = IsSharedFieldView? "Delete Shared Field" :"Delete Field" ,
Command = DeleteFieldCommand
}
}
};
}
}
Upvotes: 1
Views: 2522
Reputation: 1442
Solution that worked :
Initially i was binding a ContextMenu from my view model and the isEnabled was not working.
Instead of that I created the context menu in xaml and bound the itemsSource from the viewModel.
Now the menu item gets disabled and the triggers are working.
Not sure what i was doing wrong but this fixed it :)
Upvotes: 0
Reputation: 16618
The trick here, is that ContextMenu actually inherits from ItemsControl, this works on my machine:
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
this.DataContext = this;
InitializeComponent();
MenuItems = new ObservableCollection<KeyValuePair<string, ICommand>>();
MenuItems.Add(new KeyValuePair<string, ICommand>("One", OneCommand));
MenuItems.Add(new KeyValuePair<string, ICommand>("Two", null));
}
public ObservableCollection<KeyValuePair<String, ICommand>> MenuItems { get; set; }
#region OneCommand
DelegateCommand _OneCommand;
public DelegateCommand OneCommand
{
get { return _OneCommand ?? (_OneCommand = new DelegateCommand(One, CanOne)); }
}
public bool CanOne()
{
return false;
}
public void One()
{
}
#endregion
}
And the XAML:
<Window x:Class="DynamicContextMenuTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Path Data="M 10,2 L 17.5,2 L 17.5,0 L 23,4.5 L 17.5,9 L 17.5,7.3 L 10,7.3 L 10,2" Fill="Green">
<Path.ContextMenu>
<ContextMenu ItemsSource="{Binding MenuItems}" DisplayMemberPath="Key">
<ContextMenu.Resources>
<Style TargetType="MenuItem">
<Setter Property="Command" Value="{Binding Value}" />
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
</ContextMenu.Resources>
</ContextMenu>
</Path.ContextMenu>
</Path>
</Grid>
</Window>
Notice a few things:
string
(Header)/ICommand
(Command)CanExecute
returns false, the bound control's IsEnabled
property becomes false. You can have a trigger on that property to modify the appearance of the bound control.Upvotes: 3
Reputation: 12295
<Window.Resources>
<Style TargetType="{x:Type MenuItem}">
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="Black"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<TextBox >
<TextBox.ContextMenu>
<ContextMenu>
<Menu>
<MenuItem Header="Add" IsEnabled="False"/>
<MenuItem Header="Delete"/>
</Menu>
</ContextMenu>
</TextBox.ContextMenu>
</TextBox>
</Grid>
Its just demo and you can have idea from this . and you can bind IsEnabled to your VM Command.CanExecute . I hope this will help.
Upvotes: 1