Это просто обходной путь, но он будет работать для каждой ширины столбца MenuItem.
Результаты изменятся с этого
На Это
Все в меню строится динамически, за исключением иконки меню "Колонка"
Используя Snoop, мы видим, что оно на самом деле состоит из трех прямоугольников
Первый прямоугольник получил ширину 28
Второй прямоугольник получил ширину 1 и маржу (29, 2, 0, 2)
Третий прямоугольник получил ширину1 и поле (30, 2, 0, 2)
Я исправил это, добавив событие Loaded для самого широкого значка меню, подобного этому.
<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>
И затем изменил ширинуи поля трех прямоугольников, как это.
ОБНОВЛЕНИЕ
Дерево визуалов выглядело немного иначе для .NET 3.5, как указывает unforgiven3, это обновление исправит это.
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
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);
}
}
}