What is the best way to only enable context menu items when an image's Source
property is not null? Here is the XAML:
<Window.Resources>
<local:IsNullValueConverter x:Key="IsNullValueConverter" />
<local:NotNullValueConverter x:Key="NotNullValueConverter" />
</Window.Resources>
<DockPanel>
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
<Button Content="Fill" IsEnabled="{Binding ElementName=TheImage, Path=Source, Converter={StaticResource IsNullValueConverter}}" Click="Fill_Click" />
<Button Content="Erase" IsEnabled="{Binding ElementName=TheImage, Path=Source, Converter={StaticResource NotNullValueConverter}}" Click="Erase_Click" />
</StackPanel>
<Grid DockPanel.Dock="Bottom" Background="White">
<Grid.ContextMenu>
<ContextMenu>
<MenuItem Header="Fill" IsEnabled="{Binding ElementName=TheImage, Path=Source, Converter={StaticResource IsNullValueConverter}}" Click="Fill_Click" />
<MenuItem Header="Erase" IsEnabled="{Binding ElementName=TheImage, Path=Source, Converter={StaticResource NotNullValueConverter}}" Click="Erase_Click" />
</ContextMenu>
</Grid.ContextMenu>
<Image Name="TheImage" />
</Grid>
</DockPanel>
and here is the code:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Fill_Click(object sender, RoutedEventArgs e)
{
int width = 1;
int height = 1;
var format = PixelFormats.Gray8;
var pixels = new byte[width * height * (format.BitsPerPixel / 8)];
TheImage.Source = BitmapSource.Create(width, height, 96.0, 96.0, format, null, pixels, width * (format.BitsPerPixel / 8));
}
private void Erase_Click(object sender, RoutedEventArgs e)
{
TheImage.Source = null;
}
}
public class IsNullValueConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value == null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class NotNullValueConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value != null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
The buttons react exactly how I want: only fill is enabled initially, then once you click it and the image is filled, it is disabled while erase becomes enabled. However the context menu items are both enabled the entire time, despite their IsEnabled
properties using the exact same binding as the buttons.