这只是一个解决方法,但对于MenuItem的列,它可以适用于每个宽度。
结果将从此改变
菜单中的所有内容都是动态构建的,除了菜单的图标“Column”
使用Snoop我们可以看到它实际上是由三个矩形组成的
第一个矩形的宽度是28
第三个矩形的宽度为1,边距为(30,2,0,2)
我通过为最宽的菜单图标添加一个加载的事件来解决了这个问题。
<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>
然后像这样改变三个矩形的宽度和边距。
正如unforgiven3所指出的,对于.NET 3.5,可视化树看起来有点不同,这个更新将修复这个问题。
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助手方法的一些实现
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);
}
}
}