如何更改WPF菜单的图标列大小? [英] How do I change WPF Menu's icon column size?

查看:592
本文介绍了如何更改WPF菜单的图标列大小?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个如下所示的WPF ContextMenu:

I have a WPF ContextMenu that looks like this:

<ContextMenu Width="300">
    <MenuItem Command="{Binding MainWindowViewModel.NewCommand}">
       <MenuItem.Icon>
           <Image Source="pack://application:,,,/EAV.UI;component/Resources/Icons/MenuNew.png" Width="32" Height="32"/>
       </MenuItem.Icon>
       <MenuItem.HeaderTemplate>
           <DataTemplate>
              <TextBlock Text="New" HorizontalAlignment="Left" VerticalAlignment="Center"/>
           </DataTemplate>
       </MenuItem.HeaderTemplate>
    </MenuItem>
</ContextMenu>

问题是图标与图标列重叠,如下所示:

The problem is that the icon overlaps the icon column, like this:

如何增加菜单图标列的宽度,以使大图标位于该列的中心?

How do I increase the width of the Menu's icon column so that the large icon is centered within the column?

推荐答案

这只是一种解决方法,但适用于MenuItem列的每个宽度.
结果将从此

This a just a workaround but it'll work for every width for a MenuItem's column.
The results will change from this

为此

菜单中的所有内容都是动态生成的,但菜单的图标列"除外
使用Snoop,我们可以看到它实际上是由三个矩形组成的

Everything in the Menu is built dynamically except for the Menu's Icon "Column"
Using Snoop we can see that it's actually built up of three Rectangles

第一个矩形的宽度为28
第二个矩形的宽度为1,边距为(29,2,0,2)
第三个矩形的宽度为1,边距为(30,2,0,2)

The first Rectangle got a Width of 28
The second Rectangle got a Width of 1 and a Margin of (29, 2, 0, 2)
The third Rectangle got a Width of 1 and a Margin of (30, 2, 0, 2)

我通过为最宽的菜单图标添加一个Loaded事件来解决此问题.

I fixed this by adding a Loaded event for the widest Menu Icon like this.

<ContextMenu Width="300">  
    <MenuItem Command="{Binding MainWindowViewModel.NewCommand}">  
        <MenuItem.Icon>  
            <Image Source="pack://application:,,,/EAV.UI;component/Resources/Icons/MenuNew.png"
                   Width="32"
                   Height="32"
                   Loaded="WidestImage_Loaded"/>
       </MenuItem.Icon>  
       <MenuItem.HeaderTemplate>  
           <DataTemplate>  
               <TextBlock Text="New" HorizontalAlignment="Left" VerticalAlignment="Center"/>  
           </DataTemplate>  
       </MenuItem.HeaderTemplate>  
    </MenuItem>  
</ContextMenu>  

然后像这样更改三个矩形的宽度和边距.

And then changed the Width and Margin of the three Rectangles like this.

更新
unforgiven3指出,.NET 3.5的可视树看起来有些不同,此更新将解决该问题.

UPDATE
The Visual Tree was looking a little bit different for .NET 3.5 as pointed out by unforgiven3, this update will fix that.

private void WidestImage_Loaded(object sender, RoutedEventArgs e)
{
    Image image = sender as Image;
    StackPanel parentStackPanel = VisualTreeHelpers.GetVisualParent<StackPanel>(image);
    Grid grid = VisualTreeHelpers.GetVisualParent<Grid>(parentStackPanel);
    List<Rectangle> rectangles = VisualTreeHelpers.Get1stLevelVisualChildCollection<Rectangle>(grid);
    // .NET 3.5 fix
    if (rectangles.Count == 0)
    {
        ScrollViewer scrollViewer = VisualTreeHelpers.GetVisualParent<ScrollViewer>(grid);
        grid = VisualTreeHelpers.GetVisualParent<Grid>(scrollViewer);
        rectangles = VisualTreeHelpers.Get1stLevelVisualChildCollection<Rectangle>(grid);
    }

    double width = Math.Max(28, image.Width + 4);
    // 28
    rectangles[0].Width = width;
    // 28+1 = 29
    rectangles[1].Margin = new Thickness(width+1, 2, 0, 2);
    // 28+2 = 30
    rectangles[2].Margin = new Thickness(width+2, 2, 0, 2);
}

以及VisualTree Helper方法的一些实现

And some implementation of the VisualTree Helper methods

public static T GetVisualParent<T>(object childObject) where T : Visual
{
    DependencyObject child = childObject as DependencyObject;
    // iteratively traverse the visual tree
    while ((child != null) && !(child is T))
    {
        child = VisualTreeHelper.GetParent(child);
    }
    return child as T;
}
public static List<T> Get1stLevelVisualChildCollection<T>(object parent) where T : Visual
{
    List<T> visualCollection = new List<T>();
    Get1stLevelVisualChildCollection(parent as DependencyObject, visualCollection);
    return visualCollection;
}
private static void Get1stLevelVisualChildCollection<T>(DependencyObject parent, List<T> visualCollection) where T : Visual
{
    int count = VisualTreeHelper.GetChildrenCount(parent);
    for (int i = 0; i < count; i++)
    {
        DependencyObject child = VisualTreeHelper.GetChild(parent, i);
        if (child is T)
        {
            visualCollection.Add(child as T);
        }
    }
}

这篇关于如何更改WPF菜单的图标列大小?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆