在WPF中,我是以编程方式向控件添加上下文菜单。
var contextMenu = new ContextMenu();
contextMenu.Items.Add(new MenuItem { Header = "Copy All", Icon = FindResource("CopyImage") });
contextMenu.Items.Add(new MenuItem { Header = "Copy All with Headers", Icon = FindResource("CopyImage") });
contextMenu.Items.Add(new MenuItem { Header = "Copy Selected", Icon = FindResource("CopyImage") });
contextMenu.Items.Add(new MenuItem { Header = "Copy Selected with Headers", Icon = FindResource("CopyImage") });
CopyImage
在我的应用程序资源中定义。
<Image x:Key="CopyImage" Source="../Images/copy.png"/>
在运行时,只有最后一个菜单项显示图标。其他三个菜单项没有。
有没有人对此行为有解释?
答案 0 :(得分:8)
看看这个article。
它解释了图像一次只能在一个地方使用。这可以解释为什么它最终只会出现在代码中的最新作业。相反,定义一个BitmapImage,然后使用BitmapImage作为每个菜单项的源来创建一个新图像。
来自其他文章:
为此,在某处创建一个BitmapSource作为资源:
<BitmapImage x:Key="MyImageSource" UriSource="../Media/Image.png" />
然后,在您的代码中,使用类似:
的内容<Image Source="{StaticResource MyImageSource}" />
答案 1 :(得分:4)
每个UI元素只能放置在可视树中的一个位置。您无法在多个MenuItem上使用相同的Image控件。您需要为每个MenuItem创建单独的Image控件。否则,每次将其分配给新的MenuItem时,只需将其从一个菜单移动到另一个菜单项。
<Image x:Key="CopyImage1" Source="../Images/copy.png"/>
<Image x:Key="CopyImage2" Source="../Images/copy.png"/>
<Image x:Key="CopyImage3" Source="../Images/copy.png"/>
<Image x:Key="CopyImage4" Source="../Images/copy.png"/>
var contextMenu = new ContextMenu();
contextMenu.Items.Add(new MenuItem { Header = "Copy All", Icon = FindResource("CopyImage1") });
contextMenu.Items.Add(new MenuItem { Header = "Copy All with Headers", Icon = FindResource("CopyImage2") });
contextMenu.Items.Add(new MenuItem { Header = "Copy Selected", Icon = FindResource("CopyImage3") });
contextMenu.Items.Add(new MenuItem { Header = "Copy Selected with Headers", Icon = FindResource("CopyImage4") });
答案 2 :(得分:3)
试试这个Icon = new BitmapImage(new Uri("images/copy.png", UriKind.Relative))
var contextMenu = new ContextMenu();
contextMenu.Items.Add(new MenuItem { Header = "Copy All", Icon = new BitmapImage(new Uri("images/copy.png", UriKind.Relative)) });
contextMenu.Items.Add(new MenuItem { Header = "Copy All with Headers", Icon = new BitmapImage(new Uri("images/copy.png", UriKind.Relative)) });
contextMenu.Items.Add(new MenuItem { Header = "Copy Selected", Icon = new BitmapImage(new Uri("images/copy.png", UriKind.Relative)) });
contextMenu.Items.Add(new MenuItem { Header = "Copy Selected with Headers", Icon = new BitmapImage(new Uri("images/copy.png", UriKind.Relative)) });
答案 3 :(得分:0)
所有答案都很有帮助。以下是基于@NathanA的指针最终做的事情:
var contextMenu = new ContextMenu();
contextMenu.Items.Add(new MenuItem
{
Header = "Copy All",
Icon = new Image {Source = FindResource("CopyImageSource") as ImageSource}
});
contextMenu.Items.Add(new MenuItem
{
Header = "Copy All with Headers",
Icon = new Image {Source = FindResource("CopyImageSource") as ImageSource}
});
contextMenu.Items.Add(new MenuItem
{
Header = "Copy Selected",
Icon = new Image {Source = FindResource("CopyImageSource") as ImageSource}
});
contextMenu.Items.Add(new MenuItem
{
Header = "Copy Selected with Headers",
Icon = new Image {Source = FindResource("CopyImageSource") as ImageSource}
});
这在资源词典中:
<BitmapImage x:Key="CopyImageSource" UriSource="../Images/copy.png"/>
答案 4 :(得分:-1)
对于适用于任何类型且保持灵活性的解决方案,我使用了转换器。
这使您可以灵活地根据结果返回完全不同的组件。就我而言,虽然我只绑定到十六进制值。
XAML
<ContextMenu d:DataContext="{d:DesignInstance Type=applicantDetails:ApplicantSelections}" x:Key="HeatContextMenu" DataContext="{x:Static applicantDetails:ApplicantSelections.StaticRefApplicantSelections}" ItemsSource="{Binding TodoHeats}">
<ContextMenu.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="Icon" Value="{Binding HexColour, Converter={StaticResource HeatMenuItemConverter}}" >
</Setter>
</Style>
</ContextMenu.ItemContainerStyle>
<ContextMenu.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Description}" d:DataContext="{d:DesignInstance Type=todoManager:TodoHeat}"></TextBlock>
</DataTemplate>
</ContextMenu.ItemTemplate>
</ContextMenu>
转换器
class HeatMenuItemConverter : IValueConverter
{
/// <summary>
/// Converts the specified value.
/// </summary>
/// <param name="value">The value.</param>
/// <param name="targetType">Type of the target.</param>
/// <param name="parameter">The parameter.</param>
/// <param name="culture">The culture.</param>
/// <returns></returns>
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
Border border = new Border();
border.BorderBrush = Brushes.Black;
Rectangle rectangle = new Rectangle();
border.Child = rectangle;
rectangle.Height = 50;
rectangle.Width = 50;
try
{
if (value != null && value is string hexCode)
{
rectangle.Fill = (SolidColorBrush)new BrushConverter().ConvertFromString(hexCode);
}
}
catch (Exception e)
{
// ignored
}
return border;
}
/// <summary>
/// Converts it back.
/// </summary>
/// <param name="value">The value.</param>
/// <param name="targetType">Type of the target.</param>
/// <param name="parameter">The parameter.</param>
/// <param name="culture">The culture.</param>
/// <returns>Converted Value</returns>
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value;
}
}