为什么我的listview会继续在LargeIcon View中绘图?

我有一个inheritance的Listview,标准必须在Tile模式下。 当使用这个控件时,DrawItem给出的e.bounds明显是largeIcon视图的界限? 在调试以检查它实际设置为的视图时,它说它在Tile视图中? 然而e.DrawText绘制LargeIcon视图??

………编辑:……………..

这似乎只有在控件放在另一个用户控件上时才会发生?

………编辑2:……………..

它变得陌生……当我在列表旁边添加按钮以在运行时更改视图时, “Tile”与“LargeIcon”相同,而“List”视图与“SmallIcons”相同??? 我也完全删除了所有者…

……….编辑3:……………..

MSDN文档:平铺视图

每个项目都显示为一个完整大小的图标,其右侧有项目标签和子项目信息。 出现的子项信息由应用程序指定。 此视图仅适用于Windows XP和Windows Server 2003家族。 在早期的操作系统上,此值将被忽略,ListView控件将显示在LargeIcon视图中。

那我在XP上了?!?

……编辑4 …………………

陌生的神圣母亲……我们现在已经完全剥离了所有……我们在表格上有一个标准的列表视图,手动填充3个值。 没有所有者。 它设置为Tile。 当我们开始这个表单时,列表被绘制为LARGEICON。

现在,我们开始另一个空白解决方案,将这个完全相同的表单复制到新项目中,启动调试并低调看看它在TILE视图中绘制????

… 救命 …

public class InheritedListView : ListView { //Hiding members ... mwuahahahahaha //yeah i was still laughing then [BrowsableAttribute(false)] public new View View { get { return base.View; } } public InheritedListView() { base.View = View.Tile; this.OwnerDraw = true; base.DrawItem += new DrawListViewItemEventHandler(DualLineGrid_DrawItem); } void DualLineGrid_DrawItem(object sender, DrawListViewItemEventArgs e) { View v = this.View; //**when debugging, v is Tile, however e.DrawText() draws in LargeIcon mode, // e.Bounds also reflects LargeIcon mode ???? ** } 

…………………………..

此代码在不同的解决方案中表现不同:

  private void InitializeComponent() { System.Windows.Forms.ListViewItem listViewItem1 = new System.Windows.Forms.ListViewItem("fhsdhdsfhsdfhs"); System.Windows.Forms.ListViewItem listViewItem2 = new System.Windows.Forms.ListViewItem("fdshdsfhdsfhsd"); System.Windows.Forms.ListViewItem listViewItem3 = new System.Windows.Forms.ListViewItem("hdshsdfhsdfhsdfsdfsdf"); this.listView1 = new System.Windows.Forms.ListView(); this.SuspendLayout(); // // listView1 // this.listView1.Items.AddRange(new System.Windows.Forms.ListViewItem[] { listViewItem1, listViewItem2, listViewItem3}); this.listView1.Location = new System.Drawing.Point(36, 12); this.listView1.Name = "listView1"; this.listView1.Size = new System.Drawing.Size(487, 242); this.listView1.TabIndex = 2; this.listView1.TileSize = new System.Drawing.Size(480, 50); this.listView1.UseCompatibleStateImageBehavior = false; this.listView1.View = System.Windows.Forms.View.Tile; // // TestControl // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(595, 712); this.Controls.Add(this.listView1); this.Name = "TestControl"; this.Text = "TestControl"; this.ResumeLayout(false); } #endregion 

好的,我们找到了。 魔法是:

 Application.EnableVisualStyles(); 

我们跳过这行代码来测试我们的表单。 如果在使用列表视图创建表单之前未调用此方法,则TILE视图将被绘制为LARGEICON。

似乎完全合乎逻辑…… 🙁

http://blogs.msdn.com/rprabhu/archive/2003/09/28/56540.aspx

问Application.EnableVisualStyles实际上做了什么?

Windows XP附带两个版本的Common Controls Library(comctl32.dll) – 版本5.8和6.0。 v5.8呈现您在Windows NT / 2000和Windows 9x上获得的“经典”样式的控件。 v6.0使用XP Visual Styles外观呈现控件。 由于大多数Windows窗体控件都基于comctl32,因此它们的呈现方式取决于使用哪个版本的comctl32进行渲染。 默认情况下,v5.8用于呈现应用程序的客户区域,v6.0用于呈现非客户区域。 这就是为什么你看到标题栏和窗口边框自动呈现“主题”,而控件(如Button,TextBox,ListView,ComboBox等)默认具有经典外观。

在框架的v1.0中,在Windows窗体应用程序中获取视觉样式的方法是使用应用程序发送清单文件,其中包含信息以指示应使用v6.0的comctl32进行渲染。 虽然这很好用,但许多开发人员认为创建,维护和部署清单文件很麻烦。 他们认为有必要能够以编程方式执行此操作。 现在,Platform SDK确实提供了API来执行此操作。 基本上,您需要创建并激活激活上下文,该上下文中的DLL重定向信息与清单文件几乎相同。 激活上下文API可用于以适合您的应用程序的方式执行此操作。

如果您看一下这些API,您可能会注意到它们不是很容易使用。 虽然高级开发人员可能喜欢修改激活上下文,但开发人员可能不希望获得一些“快速而肮脏”的代码来获得视觉样式。 因此,Windows Forms团队决定包装这些API并公开一个开发人员可以调用的简单方法,这将使他们与这些复杂性隔离开来。 因此,基本上,当您调用Application.EnableVisualStyles时,我们围绕应用程序的消息循环设置激活上下文,以便可以将comctl32函数调用正确地重定向到comctl32 v6.0。 这样,您就不需要在应用中加入清单。