How do I change WPF Menu's icon column size?

前端 未结 1 1448
悲哀的现实
悲哀的现实 2020-12-11 08:41

I have a WPF ContextMenu that looks like this:


    
           


        
1条回答
  •  庸人自扰
    2020-12-11 09:04

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

    alt text

    To This

    alt text

    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

    alt text

    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)

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

      
          
              
                
             
             
                 
                     
                 
             
          
      
    

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

    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(image);
        Grid grid = VisualTreeHelpers.GetVisualParent(parentStackPanel);
        List rectangles = VisualTreeHelpers.Get1stLevelVisualChildCollection(grid);
        // .NET 3.5 fix
        if (rectangles.Count == 0)
        {
            ScrollViewer scrollViewer = VisualTreeHelpers.GetVisualParent(grid);
            grid = VisualTreeHelpers.GetVisualParent(scrollViewer);
            rectangles = VisualTreeHelpers.Get1stLevelVisualChildCollection(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);
    }
    

    And some implementation of the VisualTree Helper methods

    public static T GetVisualParent(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 Get1stLevelVisualChildCollection(object parent) where T : Visual
    {
        List visualCollection = new List();
        Get1stLevelVisualChildCollection(parent as DependencyObject, visualCollection);
        return visualCollection;
    }
    private static void Get1stLevelVisualChildCollection(DependencyObject parent, List 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);
            }
        }
    }
    

    0 讨论(0)
提交回复
热议问题