如何仅在图像的来源 属性 不为空时启用上下文菜单项?
How do I enable context menu items only when an Image's Source property is not null?
当图像的 Source
属性 不为空时,仅启用上下文菜单项的最佳方法是什么?这是 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>
这是代码:
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();
}
}
}
这些按钮的反应完全符合我的要求:最初只启用填充,然后一旦您单击它并且图像被填充,它就会被禁用,同时启用擦除。然而,上下文菜单项在整个过程中都处于启用状态,尽管它们的 IsEnabled
属性使用与按钮完全相同的绑定。
我尝试了很多不同的解决方案,最终找到了一些简单有效的方法:
<MenuItem Header="Fill" IsEnabled="{Binding Source={x:Reference TheImage}, Path=Source, Converter={StaticResource IsNullValueConverter}}" Click="Fill_Click" />
<MenuItem Header="Erase" IsEnabled="{Binding Source={x:Reference TheImage}, Path=Source, Converter={StaticResource NotNullValueConverter}}" Click="Erase_Click" />
或者,可以将其添加到代码中(必须命名上下文菜单),但在 XAML 中这样做似乎更加优雅。
NameScope.SetNameScope(TheContextMenu, NameScope.GetNameScope(this));
感谢 ZSH 为我指明了正确的方向。
当图像的 Source
属性 不为空时,仅启用上下文菜单项的最佳方法是什么?这是 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>
这是代码:
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();
}
}
}
这些按钮的反应完全符合我的要求:最初只启用填充,然后一旦您单击它并且图像被填充,它就会被禁用,同时启用擦除。然而,上下文菜单项在整个过程中都处于启用状态,尽管它们的 IsEnabled
属性使用与按钮完全相同的绑定。
我尝试了很多不同的解决方案,最终找到了一些简单有效的方法:
<MenuItem Header="Fill" IsEnabled="{Binding Source={x:Reference TheImage}, Path=Source, Converter={StaticResource IsNullValueConverter}}" Click="Fill_Click" />
<MenuItem Header="Erase" IsEnabled="{Binding Source={x:Reference TheImage}, Path=Source, Converter={StaticResource NotNullValueConverter}}" Click="Erase_Click" />
或者,可以将其添加到代码中(必须命名上下文菜单),但在 XAML 中这样做似乎更加优雅。
NameScope.SetNameScope(TheContextMenu, NameScope.GetNameScope(this));
感谢 ZSH 为我指明了正确的方向。