Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

c# - Why does my listview keep drawing in LargeIcon View?

I have a inherited Listview which standard has to be in Tile Mode. When using this control, the DrawItem gives e.bounds which are clearly bounds of largeIcon view ?? When debugging to check the view it is actually set to, it says it's in Tile view ?? Yet e.DrawText draws LargeIcon view ??

......... Edit: .................

This seems only to happen when the control is placed upon another usercontrol?

......... Edit 2: .................

It gets stranger ... When i add buttons next to the list to change the view at runtime, "Tile" is the same as "LargeIcon", and "List" view is the same as "SmallIcons" ??? I've also completely removed the ownerdraw ...

.......... Edit 3: .................

MSDN Documentation: Tile view

Each item appears as a full-sized icon with the item label and subitem information to the right of it. The subitem information that appears is specified by the application. This view is available only on Windows XP and the Windows Server 2003 family. On earlier operating systems, this value is ignored and the ListView control displays in the LargeIcon view.

Well I am on XP ?!?

...... Edit 4 .....................

Holy mother of strangeness ... We are now at the point we've completely stripped down EVERYTING ... We have a standard listview on a form, manually filled with 3 values. No Ownerdraw. It is set to Tile. When we start this form, the list is drawn as LARGEICON.

Now, we start another blank solution, copy this exact same form to the new project, start debug and low and behold .. it is drawn in TILE view ????

... help ...

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 ???? **
     }

................................

This code behaves differently at different solutions:

    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
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

OK, we found it. The magic spell is:

Application.EnableVisualStyles();

We skipped this line of code to test our form. If you don't call this method before you create your form with your listview, TILE view gets drawn as LARGEICON.

Seems totally logical ... :-(

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

Q What does Application.EnableVisualStyles actually do?

Windows XP ships with two versions of the Common Controls Library (comctl32.dll) - versions 5.8 and 6.0. v5.8 renders controls in the "Classic" style that you get on Windows NT/2000 and Windows 9x. v6.0 renders controls using the XP Visual Styles look and feel. Since most Windows Forms controls are based on comctl32, how they are rendered depends on which version of comctl32 is used to do the rendering. By default, v5.8 is used to render the client area of the app and v6.0 is used to render the non-client area. That is why you see the title bar and window borders automatically render "themed", while the controls (like Button, TextBox, ListView, ComboBox and so on) have the classic look by default.

In v1.0 of the Framework, the way to get visual styles in a Windows Forms app was to ship a manifest file with the app, that has information in it to indicate that v6.0 of comctl32 should be used for rendering. While this works fine, many developers felt it cumbersome to author, maintain and deploy manifest files. They felt the need to be able to do this programmatically. Now, the Platform SDK does provide API to do this. Basically, you need to create and activate an Activation Context that has pretty much the same DLL redirection information in it as the manifest file. The Activation Context API can be used to do this in a way suitable to your application.

If you take a look at these API, you will probably notice that they aren't very easy to use. While the advanced developers may like to tinker around with activation contexts, it is probably not something a developer who wants some "quick and dirty" code to get visual styles will do. So the Windows Forms team decided to wrap these API and expose a simple method that developers could call, that would isolate them from these complexities. So, essentially, when you call Application.EnableVisualStyles, we set up an activation context around the application's message loop, so that comctl32 function calls can be properly redirected to comctl32 v6.0. That way, you don't need to include a manifest with your app.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...