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

时间:2010-05-20 13:47:44

标签: c# .net listview

我有一个继承的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

1 个答案:

答案 0 :(得分:3)

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

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等)默认具有经典外观。

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

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