我使用一个包含ListView的简单表单创建了新的Windows窗体应用程序(C#)。然后我将View Property更改为Details并增加了此ListView中使用的字体大小,结果如下:
这是Windows XP上使用Windows经典主题的外观:
以下是Windows XP主题的结果:
通过删除Application.EnableVisualStyles()
调用或更改,我可以阻止我的应用程序的外观受到Visual Styles的影响
Application.VisualStyleState
:
虽然此更改使ListView具有所需的外观,但它也会影响其他控件的外观。我希望我的ListView是唯一不受视觉样式影响的控件。
我也发现了类似的问题,试图解决它:
Can you turn off visual styles/theming for just a single windows control?
How do I disable visual styles for just one control, and not its children?
不幸的是,所提到的解决方案都不起作用。 看起来标题本身将由一些受视觉样式影响的控件组成,即使禁用了ListView控件的视觉样式也是如此。
任何阻止视觉样式影响ListView标题外观的C#解决方案都将受到赞赏。
答案 0 :(得分:3)
看起来这是一个known bug,没有简单的解决方法。根据那里的答案:
在对这个问题做了大量研究之后,我们发现这是一个 Windows操作系统错误,ComCtl6.0标头控件忘记应用 绘图DC的字体信息。
但是您可以自己绘制列标题。有关如何操作的详细信息,请参阅this article on MSDN,并查看listView1_DrawColumnHeader
。
答案 1 :(得分:2)
禁用视觉样式怎么样?
使用此代码可以禁用一个控件的样式(只使用ListViewConstrol而不是ListView):
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
public class ListViewControl : ListView {
[DllImportAttribute("uxtheme.dll")]
private static extern int SetWindowTheme(IntPtr hWnd, string appname, string idlist);
protected override void OnHandleCreated(EventArgs e) {
SetWindowTheme(this.Handle, "", "");
base.OnHandleCreated(e);
}
}
答案 2 :(得分:2)
经过深思熟虑的研究后,我发现了它。问题是,当你打电话
SetWindowTheme(this.Handle, "", "");
在自定义ListView
类中,它会阻止视觉样式影响ListView
控件的外观,但不会影响ListView
标题控件(SysHeader32
窗口)的外观ListView
的窗口。 因此,在调用SetWindowTheme
函数时,我们需要提供标题窗口的句柄而不是ListView的句柄:
[DllImportAttribute("uxtheme.dll")]
private static extern int SetWindowTheme(IntPtr hWnd, string appname, string idlist);
[DllImport("user32")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr i);
// Callback method to be used when enumerating windows:
private static bool EnumWindow(IntPtr handle, IntPtr pointer)
{
GCHandle gch = GCHandle.FromIntPtr(pointer);
List<IntPtr> list = gch.Target as List<IntPtr>;
if (list == null)
throw new InvalidCastException("GCHandle Target could not be cast as List<IntPtr>");
list.Add(handle);
return true;
}
// delegate for the EnumChildWindows method:
private delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter);
// get first child:
private static void DisableVisualStylesForFirstChild(IntPtr parent)
{
List<IntPtr> children = new List<IntPtr>();
GCHandle listHandle = GCHandle.Alloc(children);
try
{
EnumWindowProc childProc = new EnumWindowProc(EnumWindow);
EnumChildWindows(parent, childProc, GCHandle.ToIntPtr(listHandle));
if (children.Count > 0)
SetWindowTheme(children[0], "", "");
}
finally
{
if (listHandle.IsAllocated)
listHandle.Free();
}
}
protected override void OnHandleCreated(EventArgs e)
{
DisableVisualStylesForFirstChild(this.Handle);
base.OnHandleCreated(e);
}
答案 3 :(得分:0)
正如Botz3000在他的回答中提到的那样,它是Windows XP中ListView
的一个众所周知的问题。另一种解决方法是注册ListView.DrawColumnHeader
事件并重置其中的标题字体。您必须将ListView.OwnerDraw
属性设置为true
。 MSDN代码如下;
// Draws column headers.
private void listView1_DrawColumnHeader(object sender,
DrawListViewColumnHeaderEventArgs e)
{
using (StringFormat sf = new StringFormat())
{
// Store the column text alignment, letting it default
// to Left if it has not been set to Center or Right.
switch (e.Header.TextAlign)
{
case HorizontalAlignment.Center:
sf.Alignment = StringAlignment.Center;
break;
case HorizontalAlignment.Right:
sf.Alignment = StringAlignment.Far;
break;
}
// Draw the standard header background.
e.DrawBackground();
// Draw the header text.
using (Font headerFont =
new Font("Helvetica", 10, FontStyle.Bold))
{
e.Graphics.DrawString(e.Header.Text, headerFont,
Brushes.Black, e.Bounds, sf);
}
}
return;
}
在这种情况下,标题字体将始终为"Helvetica", 10, FontStyle.Bold
,并且不受listview字体的影响。 Check MSDN了解更多详情。
答案 4 :(得分:0)
以下是如何使ListView标题具有您想要的高度: