這只是一個解決方法,但它將適用於MenuItem列的每個寬度。
結果將從此
![alt text](https://i.stack.imgur.com/IVxDq.png)
改變要在菜單此
![alt text](https://i.stack.imgur.com/2m9RT.png)
一切都是動態構建除了菜單的圖標「列」
使用snoop我們可以看到它實際上由三個矩形組成
![alt text](https://i.stack.imgur.com/rqn0P.png)
第一矩形得到的28
一個寬度的第二個矩形得到1:1的寬度和的餘量(29,2,0,2)
第三矩形得到1: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>
然後改變這三個矩形的寬度和邊距。
UPDATE
可視樹是由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 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);
}
}
}
一些實施好像你需要改變你的菜單項的模板。我建議使用Blend編輯模板或查看Kaxaml的SimpleStyles。 – robertos 2010-10-31 10:15:07