如何更改WPF菜单';s图标列大小?
我有一个WPF上下文菜单,如下所示:如何更改WPF菜单';s图标列大小?,wpf,xaml,menu,wpf-controls,Wpf,Xaml,Menu,Wpf Controls,我有一个WPF上下文菜单,如下所示: <ContextMenu Width="300"> <MenuItem Command="{Binding MainWindowViewModel.NewCommand}"> <MenuItem.Icon> <Image Source="pack://application:,,,/EAV.UI;component/Resources/Icons/MenuNew.png"
<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>
问题是图标与图标列重叠,如下所示:
如何增加菜单图标列的宽度,使大图标位于列的中心?这只是一种解决方法,但它适用于菜单项列的每个宽度。
结果将从此改变 对此 菜单中的所有内容都是动态构建的,除了菜单的图标“列”
使用Snoop我们可以看到它实际上由三个矩形组成 第一个矩形的宽度为28
第二个矩形的宽度为1,边距为(29,2,0,2)
第三个矩形的宽度为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所指出的那样,对于.NET3.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);
}
private void widetimage\u加载(对象发送方、路由目标方)
{
图像=发送者作为图像;
StackPanel parentStackPanel=VisualTreeHelpers.GetVisualParent(图像);
Grid Grid=VisualTreeHelpers.GetVisualParent(parentStackPanel);
列表矩形=VisualTreeHelpers.Get1stLevelVisualChildCollection(网格);
//.NET3.5修复程序
如果(矩形数==0)
{
ScrollViewer ScrollViewer=VisualTreeHelpers.GetVisualParent(网格);
grid=VisualTreeHelpers.GetVisualParent(scrollViewer);
矩形=VisualTreeHelpers.Get1stLevel VisualChildCollection(网格);
}
双宽度=数学最大值(28,图像宽度+4);
// 28
矩形[0]。宽度=宽度;
// 28+1 = 29
矩形[1]。边距=新厚度(宽度+1,2,0,2);
// 28+2 = 30
矩形[2]。边距=新厚度(宽度+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);
}
}
}
publicstatict GetVisualParent(objectchildobject),其中T:Visual
{
DependencyObject子对象=作为DependencyObject的子对象;
//迭代遍历可视化树
while((child!=null)&&&!(child是T))
{
child=visualtreeheloper.GetParent(child);
}
返回子对象作为T;
}
公共静态列表Get1stLevelVisualChildCollection(对象父对象),其中T:Visual
{
List visualCollection=新列表();
Get1stLevelVisualChildCollection(父对象作为DependencyObject,visualCollection);
返回视觉采集;
}
私有静态void Get1stLevelVisualChildCollection(DependencyObject父对象,列表visualCollection),其中T:Visual
{
int count=VisualTreeHelper.GetChildrenCount(父级);
for(int i=0;i
似乎需要更改菜单项的模板。我建议使用Blend编辑模板,或者查看Kaxaml的SimpleStyles。对于.NET3.5,可视化树看起来有点不同。更新了我的答案。