Home All Groups Group Topic Archive Search About

Error in Treeview with Checkboxes and Vista

Author
31 Oct 2007 10:40 AM
Dieter Pelz
Hallo,

there is an error in the TreeView control when checkboxes are enabled.
When the checkbox is double clicked the node is visibly not checked, but the
Checked property is still true;

I'm using Visual Studio 2005.
Windows Vista und Vista 64 has this error.
Windows XP works fine.

Is there any workaround for this Error?
An example project is available.

Thanks,
Dieter Pelz

Author
1 Nov 2007 7:25 AM
Linda Liu[MSFT]
Hi Dieter,

I performed a test based on your description and did reproduce the problem
on my side.

This problem is caused by the Vista visual styles. If you disable the
visual styles for the application, the problem doesn't exist.

FYI, to disable the visual styles for a WinForm application, if you're
using C#, open the Program.cs file and comment out the line of code
'Application.EnableVisualStyles();' in the static Main method; if you're
using VB.NET, right click the project in the Solution Explorer and choose
Properties, in the Project Designer, switch to Application tab and clear
the checkbox before the option 'Enable XP visual styles'.

So, the easiest workaround of this problem is to disable the Vista visual
styles for the application.

A more complicated workaround is to draw the TreeView by ourselves so that
we can ensure the displayed check state of the treenode is always correct.
To do this, we need to set the DrawMode of the TreeView to OwnerDrawAll and
handle the DrawNode event of the TreeView. In addition, we need to add two
bmp files to the application. One bmp file represents the plus sign used by
the TreeView and the other represents the minus sign.

The following is a sample to do this:

public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.treeView1.DrawMode = TreeViewDrawMode.OwnerDrawAll;
            this.treeView1.DrawNode += new
DrawTreeNodeEventHandler(treeView1_DrawNode);
        }

        void treeView1_DrawNode(object sender, DrawTreeNodeEventArgs e)
        {           
            int left = e.Bounds.X;
            int top = e.Bounds.Y;
            int height = e.Bounds.Height;

            int nodeleft = e.Node.Bounds.X;
            int nodetop = e.Node.Bounds.Y;
            int nodeheight = e.Node.Bounds.Height;
            int nodewidth = e.Node.Bounds.Width;

            int linelength =10;
            int checkboxwidth = 13;
            int checknodespace = 2;
            using (Pen p = new Pen(Color.Gray))
            {
                p.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
                int lineleft =
nodeleft-checknodespace-checkboxwidth-linelength;
                //draw horizontal dot line
                e.Graphics.DrawLine(p, lineleft, top + height / 2, lineleft
+ linelength, top + height / 2);
                // draw the up half vertical dot line
                if (e.Node.PrevNode != null || e.Node.Parent != null)
                {
                    e.Graphics.DrawLine(p, lineleft, top, lineleft, top +
height / 2);
                }
                // draw the down half vertical dot line
                if (e.Node.NextNode != null)
                {
                    e.Graphics.DrawLine(p, lineleft, top + height / 2,
lineleft, e.Node.NextNode.Bounds.Top);
                }
                // draw plus/minus image
                if (e.Node.Nodes.Count > 0)
                {
                    if (!e.Node.IsExpanded)
                    {
                        e.Graphics.DrawImage(Properties.Resources.plus,
lineleft - Properties.Resources.plus.Width / 2, top + (height -
Properties.Resources.plus.Height) / 2);
                    }
                    else
                    {
                        e.Graphics.DrawImage(Properties.Resources.minus,
lineleft - Properties.Resources.minus.Width / 2, top + (height -
Properties.Resources.minus.Height) / 2);
                    }                           
                }
                // draw the vertical dot line for the parent nodes if
necessary
                TreeNode parentNode = e.Node.Parent;
                int parentNodeLeftDistance = checknodespace + checkboxwidth
+ linelength;
                while (parentNode != null)
                {
                    if (parentNode.NextNode != null)
                    {
                        e.Graphics.DrawLine(p, parentNode.Bounds.X -
parentNodeLeftDistance, top, parentNode.Bounds.X - parentNodeLeftDistance,
top + height);
                    }
                    parentNode = parentNode.Parent;
                }
            }
            // draw checkbox
            if (e.Node.Checked)
            {
                ControlPaint.DrawCheckBox(e.Graphics, new
Rectangle(nodeleft - checkboxwidth - checknodespace, top + (height -
checkboxwidth) / 2, checkboxwidth, checkboxwidth), ButtonState.Checked);
            }
            else
            {
                ControlPaint.DrawCheckBox(e.Graphics, new
Rectangle(nodeleft - checkboxwidth - checknodespace, top + (height -
checkboxwidth) / 2, checkboxwidth, checkboxwidth), ButtonState.Normal);
            }
            // erase the previous node text
            using (Brush b = new SolidBrush(this.treeView1.BackColor))
            {
                e.Graphics.DrawString(e.Node.Text, this.treeView1.Font, b,
nodeleft, nodetop);
            }
            // draw node text and highlight rectangle
            if (e.Node.IsSelected)
            {
                ControlPaint.DrawFocusRectangle(e.Graphics, e.Node.Bounds);

                e.Graphics.FillRectangle(Brushes.LightSkyBlue, new
Rectangle(nodeleft + 1, nodetop + 1, nodewidth - 2, nodeheight - 2));
                using (Brush b = new SolidBrush(Color.White))
                {
                    e.Graphics.DrawString(e.Node.Text, this.treeView1.Font,
b, nodeleft, nodetop);
                }
            }
            else
            {
                using (Brush b = new SolidBrush(this.treeView1.ForeColor))
                {
                    e.Graphics.DrawString(e.Node.Text, this.treeView1.Font,
b, nodeleft, nodetop);
                }
            }         
        }
}

Hope this helps.
If you have any question, please feel free to let me know.

Sincerely,
Linda Liu
Microsoft Online Community Support

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
Author
1 Nov 2007 8:08 AM
Brendon Bezuidenhout
Linda,

Do you possibly know how to "fix" the Vista msstyles and XP VisualStyles
incompatibility possibly? For example below in the code snippet... It's
possible now to handle both XP visual styles and pre XP styles... But with
the advent of Vista things are now not as backward compatible as it were? I
understand that it is possible using the Win32 API to possibly make the code
below look as it does in Vista; but there has to be an easier way through VS
to do this rather than the SDK? (I'm using VS2005 and 2008 Beta2).

Thanks,
Brendon

<code>
public class ComboTreeButton : Button
    {
#region Fields

        private ButtonState buttonState;
        private ComboBoxState comboBoxState;

        #endregion

protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            if (!ComboBoxRenderer.IsSupported)
            {
                ControlPaint.DrawComboButton(e.Graphics,
this.ClientRectangle, buttonState );
            }
            else
            {
                ComboBoxRenderer.DrawDropDownButton(e.Graphics,
this.ClientRectangle, comboBoxState);
            }
        }
}
</code>

Show quote
"Linda Liu[MSFT]" <v-l***@online.microsoft.com> wrote in message
news:6dfGlhFHIHA.7444@TK2MSFTNGHUB02.phx.gbl...
> Hi Dieter,
>
> I performed a test based on your description and did reproduce the problem
> on my side.
>
> This problem is caused by the Vista visual styles. If you disable the
> visual styles for the application, the problem doesn't exist.
>
> FYI, to disable the visual styles for a WinForm application, if you're
> using C#, open the Program.cs file and comment out the line of code
> 'Application.EnableVisualStyles();' in the static Main method; if you're
> using VB.NET, right click the project in the Solution Explorer and choose
> Properties, in the Project Designer, switch to Application tab and clear
> the checkbox before the option 'Enable XP visual styles'.
>
> So, the easiest workaround of this problem is to disable the Vista visual
> styles for the application.
>
> A more complicated workaround is to draw the TreeView by ourselves so that
> we can ensure the displayed check state of the treenode is always correct.
> To do this, we need to set the DrawMode of the TreeView to OwnerDrawAll
> and
> handle the DrawNode event of the TreeView. In addition, we need to add two
> bmp files to the application. One bmp file represents the plus sign used
> by
> the TreeView and the other represents the minus sign.
>
> The following is a sample to do this:
>
> public partial class Form1 : Form
>    {
>        public Form1()
>        {
>            InitializeComponent();
>            this.treeView1.DrawMode = TreeViewDrawMode.OwnerDrawAll;
>            this.treeView1.DrawNode += new
> DrawTreeNodeEventHandler(treeView1_DrawNode);
>        }
>
>        void treeView1_DrawNode(object sender, DrawTreeNodeEventArgs e)
>        {
>            int left = e.Bounds.X;
>            int top = e.Bounds.Y;
>            int height = e.Bounds.Height;
>
>            int nodeleft = e.Node.Bounds.X;
>            int nodetop = e.Node.Bounds.Y;
>            int nodeheight = e.Node.Bounds.Height;
>            int nodewidth = e.Node.Bounds.Width;
>
>            int linelength =10;
>            int checkboxwidth = 13;
>            int checknodespace = 2;
>            using (Pen p = new Pen(Color.Gray))
>            {
>                p.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
>                int lineleft =
> nodeleft-checknodespace-checkboxwidth-linelength;
>                //draw horizontal dot line
>                e.Graphics.DrawLine(p, lineleft, top + height / 2, lineleft
> + linelength, top + height / 2);
>                // draw the up half vertical dot line
>                if (e.Node.PrevNode != null || e.Node.Parent != null)
>                {
>                    e.Graphics.DrawLine(p, lineleft, top, lineleft, top +
> height / 2);
>                }
>                // draw the down half vertical dot line
>                if (e.Node.NextNode != null)
>                {
>                    e.Graphics.DrawLine(p, lineleft, top + height / 2,
> lineleft, e.Node.NextNode.Bounds.Top);
>                }
>                // draw plus/minus image
>                if (e.Node.Nodes.Count > 0)
>                {
>                    if (!e.Node.IsExpanded)
>                    {
>                        e.Graphics.DrawImage(Properties.Resources.plus,
> lineleft - Properties.Resources.plus.Width / 2, top + (height -
> Properties.Resources.plus.Height) / 2);
>                    }
>                    else
>                    {
>                        e.Graphics.DrawImage(Properties.Resources.minus,
> lineleft - Properties.Resources.minus.Width / 2, top + (height -
> Properties.Resources.minus.Height) / 2);
>                    }
>                }
>                // draw the vertical dot line for the parent nodes if
> necessary
>                TreeNode parentNode = e.Node.Parent;
>                int parentNodeLeftDistance = checknodespace + checkboxwidth
> + linelength;
>                while (parentNode != null)
>                {
>                    if (parentNode.NextNode != null)
>                    {
>                        e.Graphics.DrawLine(p, parentNode.Bounds.X -
> parentNodeLeftDistance, top, parentNode.Bounds.X - parentNodeLeftDistance,
> top + height);
>                    }
>                    parentNode = parentNode.Parent;
>                }
>            }
>            // draw checkbox
>            if (e.Node.Checked)
>            {
>                ControlPaint.DrawCheckBox(e.Graphics, new
> Rectangle(nodeleft - checkboxwidth - checknodespace, top + (height -
> checkboxwidth) / 2, checkboxwidth, checkboxwidth), ButtonState.Checked);
>            }
>            else
>            {
>                ControlPaint.DrawCheckBox(e.Graphics, new
> Rectangle(nodeleft - checkboxwidth - checknodespace, top + (height -
> checkboxwidth) / 2, checkboxwidth, checkboxwidth), ButtonState.Normal);
>            }
>            // erase the previous node text
>            using (Brush b = new SolidBrush(this.treeView1.BackColor))
>            {
>                e.Graphics.DrawString(e.Node.Text, this.treeView1.Font, b,
> nodeleft, nodetop);
>            }
>            // draw node text and highlight rectangle
>            if (e.Node.IsSelected)
>            {
>                ControlPaint.DrawFocusRectangle(e.Graphics, e.Node.Bounds);
>
>                e.Graphics.FillRectangle(Brushes.LightSkyBlue, new
> Rectangle(nodeleft + 1, nodetop + 1, nodewidth - 2, nodeheight - 2));
>                using (Brush b = new SolidBrush(Color.White))
>                {
>                    e.Graphics.DrawString(e.Node.Text, this.treeView1.Font,
> b, nodeleft, nodetop);
>                }
>            }
>            else
>            {
>                using (Brush b = new SolidBrush(this.treeView1.ForeColor))
>                {
>                    e.Graphics.DrawString(e.Node.Text, this.treeView1.Font,
> b, nodeleft, nodetop);
>                }
>            }
>        }
> }
>
> Hope this helps.
> If you have any question, please feel free to let me know.
>
> Sincerely,
> Linda Liu
> Microsoft Online Community Support
>
> ==================================================
> Get notification to my posts through email? Please refer to
> http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
> ications.
>
> Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
> where an initial response from the community or a Microsoft Support
> Engineer within 1 business day is acceptable. Please note that each follow
> up response may take approximately 2 business days as the support
> professional working with you may need further investigation to reach the
> most efficient resolution. The offering is not appropriate for situations
> that require urgent, real-time or phone-based interactions or complex
> project analysis and dump analysis issues. Issues of this nature are best
> handled working with a dedicated Microsoft Support Engineer by contacting
> Microsoft Customer Support Services (CSS) at
> http://msdn.microsoft.com/subscriptions/support/default.aspx.
> ==================================================
>
> This posting is provided "AS IS" with no warranties, and confers no
> rights.
>
Author
2 Nov 2007 10:19 AM
Linda Liu[MSFT]
Hi Brendon,

> Do you possibly know how to "fix" the Vista msstyles and XP VisualStyles
incompatibility possibly?

Sorry that I don't understand your question. You sample code works fine on
my Vista machine.

Could you please explain more about your question?

Sincerely,
Linda Liu
Microsoft Online Community Support
Author
2 Nov 2007 6:18 PM
Brendon Bezuidenhout
Linda,

Put that code in a class and build the application - then add the control
created onto a form and put a combo box onto the same form... Now UNDER
VISTA run the application and look at the form... What do you notice
different? While the button is rendered correctly yes... It is not the
visual style of Vista... When I've done OwnerDrawn controls under XP to
ensure conformity in the UI I've used that block for example to ensure that
dependant on the user system and theme selected the controls look and feel
the same... Vista to XP and before this is not the way now...

Brendon

Show quote
"Linda Liu[MSFT]" <v-l***@online.microsoft.com> wrote in message
news:IzefgnTHIHA.540@TK2MSFTNGHUB02.phx.gbl...
> Hi Brendon,
>
>> Do you possibly know how to "fix" the Vista msstyles and XP VisualStyles
> incompatibility possibly?
>
> Sorry that I don't understand your question. You sample code works fine on
> my Vista machine.
>
> Could you please explain more about your question?
>
> Sincerely,
> Linda Liu
> Microsoft Online Community Support
>
Author
5 Nov 2007 9:00 AM
Linda Liu[MSFT]
Hi Brendon,

In fact, the Vista visual style of a ComboBox drop down button has three
appearances. Initially, the drop down button only shows a black triangle
sign. If you hover the mouse over the drop down button, the drop down
button appears activated. If you click on it, it appears pressed.

You can mimic the above appearances by handling the related events of the
ComboBox and pass ComboBoxState.Hot or ComboBoxState.Pressed to the
ComboBoxRenderer.DrawDropDownButton method.

Sincerely,
Linda Liu
Microsoft Online Community Support
Author
5 Nov 2007 7:26 PM
Brendon Bezuidenhout
Linda,

Please see my blog on this topic to see a screenshot of what I mean :) - I
fully understand the ComboBox model and its rendering on Windows XP and pre
XP days... my concern is the Aero and Vista days...

http://fileunderb.spaces.live.com/blog/cns!30E7F96B7150E7A7!273.entry

Brendon

Show quote
"Linda Liu[MSFT]" <v-l***@online.microsoft.com> wrote in message
news:Pt%23cNp4HIHA.7444@TK2MSFTNGHUB02.phx.gbl...
> Hi Brendon,
>
> In fact, the Vista visual style of a ComboBox drop down button has three
> appearances. Initially, the drop down button only shows a black triangle
> sign. If you hover the mouse over the drop down button, the drop down
> button appears activated. If you click on it, it appears pressed.
>
> You can mimic the above appearances by handling the related events of the
> ComboBox and pass ComboBoxState.Hot or ComboBoxState.Pressed to the
> ComboBoxRenderer.DrawDropDownButton method.
>
> Sincerely,
> Linda Liu
> Microsoft Online Community Support
>
Author
7 Nov 2007 10:46 AM
Linda Liu[MSFT]
Hi Dieter,

How about your problem now?

If you have any question, please feel free to let me know.

Thank you for using our MSDN Managed Newsgroup Support Service!

Sincerely,
Linda Liu
Microsoft Online Community Support
Author
13 Nov 2007 9:34 AM
Dieter Pelz
Hallo,

sorry for answering so late.

Will this error in the framework on Vista be fixed?
Because it seemed for me that the state of the W32 TreeView Item and the
..Net TreeView Item are not in sync!
I used Reflector to look inside the problem and it seemed to be that the
TreeItem will cache the state, but the state of the TreeViewItem in W32 is
not the same.

Disabling Visual Styles ist not the right solution for me because it is a
dialog inside a library that is used from an C++/CLI application.

Sincerely,
Dieter Pelz



Show quote
"Linda Liu[MSFT]" <v-l***@online.microsoft.com> schrieb im Newsbeitrag
news:jkim0tSIIHA.540@TK2MSFTNGHUB02.phx.gbl...
> Hi Dieter,
>
> How about your problem now?
>
> If you have any question, please feel free to let me know.
>
> Thank you for using our MSDN Managed Newsgroup Support Service!
>
> Sincerely,
> Linda Liu
> Microsoft Online Community Support
>
Author
15 Nov 2007 9:39 AM
Linda Liu[MSFT]
Hi Dieter,

Thank you for your reply!

The problem you entered has been reproduced, but our evaluation determined
that it does not meet the criteria to be addressed in this release. This
evaluation is carefully done and considers many aspects including fix cost,
breaking changes, globalization, performance, etc.

Additionally, as part of planning and analysis of future versions this bug
will be considered again for possible inclusion.

> Disabling Visual Styles ist not the right solution for me because it is a
dialog inside a library that is used from an C++/CLI application.

How about the other solution of drawing the TreeView by ourselves that I
provided in my first reply?

If you have any question, please feel free to let me know.

Sincerely,
Linda Liu
Microsoft Online Community Support
Author
15 Nov 2007 1:33 PM
Dieter Pelz
Hallo,

"Linda Liu[MSFT]" <v-l***@online.microsoft.com> schrieb im Newsbeitrag
news:Bo5vzt2JIHA.360@TK2MSFTNGHUB02.phx.gbl...
> Hi Dieter,
>
> Thank you for your reply!
>
> The problem you entered has been reproduced, but our evaluation determined
> that it does not meet the criteria to be addressed in this release. This
> evaluation is carefully done and considers many aspects including fix
> cost,
> breaking changes, globalization, performance, etc.

But this meens a WinForm App with an TreeView with Checkboxes is not usable
under Vista.
I think checkboxes will normally be used to select functions that will run
on the nodes.
In our app the checkbox will delete and change main configuration entries in
a database.
When an node is visibly not check but the state in Framework says it ist
checked the functions will run.
This makes TreeView with Checkboxes in every WinForm application not usable.

This brings me to another question:
Does this means error in the .Net Framework will not be fixed because of the
costs?
The error will not affect breaking changes and globalization aspects.
Performance could be affected because an TreeViewItem State must be asked
when a mouse button is pressed.


>
> Additionally, as part of planning and analysis of future versions this bug
> will be considered again for possible inclusion.
>
>> Disabling Visual Styles ist not the right solution for me because it is a
> dialog inside a library that is used from an C++/CLI application.
>
> How about the other solution of drawing the TreeView by ourselves that I
> provided in my first reply?

ImageLists are not attended and the look is not the same as in Vista.
What must be change to get the same look as in Vista?
What about Visual Styles?
What about the property HideSelection?

I could send you an image from a test app and an test Project.

I adopted your code in a new class TreeViewVista inherited from TreeView.
On the left side I used the new class TreeViewVista.
On the right side I used the original class TreeView.
Under every control there are labels. They will be filled with the state of
the first related TreeNode.


Here is the Code of my TreeViewVista class:
Where will I get the original bitmaps for plus and minus?
What must be added to get the same look as the original TreeView?

File: TreeViewErrorVista.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;

namespace TreeViewErrorVista
{
  public class TreeViewVista : TreeView
  {
    public TreeViewVista()
    {
      if (Environment.OSVersion.Version.Major >= 6)
      {
        DrawMode = TreeViewDrawMode.OwnerDrawAll;
        DrawNode += new DrawTreeNodeEventHandler(treeView1_DrawNode);
      }
    }



    private void treeView1_DrawNode(object sender, DrawTreeNodeEventArgs e)
    {
      int left = e.Bounds.X;
      int top = e.Bounds.Y;
      int height = e.Bounds.Height;

      int nodeleft = e.Node.Bounds.X;
      int nodetop = e.Node.Bounds.Y;
      int nodeheight = e.Node.Bounds.Height;
      int nodewidth = e.Node.Bounds.Width;

      int linelength =10;
      int checkboxwidth = 13;
      int checknodespace = 2;
      using (Pen p = new Pen(Color.Gray))
      {
        p.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
        int lineleft = nodeleft-checknodespace-checkboxwidth-linelength;
        //draw horizontal dot line
        e.Graphics.DrawLine(p, lineleft, top + height / 2, lineleft +
linelength, top + height / 2);
        // draw the up half vertical dot line
        if (e.Node.PrevNode != null || e.Node.Parent != null)
        {
          e.Graphics.DrawLine(p, lineleft, top, lineleft, top + height / 2);
        }
        // draw the down half vertical dot line
        if (e.Node.NextNode != null)
        {
            e.Graphics.DrawLine(p, lineleft, top + height / 2,
              lineleft, e.Node.NextNode.Bounds.Top);
        }
        // draw plus/minus image
        if (e.Node.Nodes.Count > 0)
        {
            if (!e.Node.IsExpanded)
            {
              e.Graphics.DrawImage(Properties.Resources.plus,
                lineleft - Properties.Resources.plus.Width / 2, top +
(height -
                Properties.Resources.plus.Height) / 2);
            }
            else
            {
              e.Graphics.DrawImage(Properties.Resources.minus,
                lineleft - Properties.Resources.minus.Width / 2, top +
(height -
                Properties.Resources.minus.Height) / 2);
            }
        }
        // draw the vertical dot line for the parent nodes if necessary
        TreeNode parentNode = e.Node.Parent;
        int parentNodeLeftDistance = checknodespace + checkboxwidth +
linelength;
        while (parentNode != null)
        {
            if (parentNode.NextNode != null)
            {
              e.Graphics.DrawLine(p, parentNode.Bounds.X -
parentNodeLeftDistance,
                top, parentNode.Bounds.X - parentNodeLeftDistance, top +
height);
            }
            parentNode = parentNode.Parent;
        }
      }
      // draw checkbox
      if (e.Node.Checked)
      {
        ControlPaint.DrawCheckBox(e.Graphics, new Rectangle(nodeleft -
checkboxwidth - checknodespace,
          top + (height - checkboxwidth) / 2, checkboxwidth, checkboxwidth),
ButtonState.Checked);
      }
      else
      {
        ControlPaint.DrawCheckBox(e.Graphics, new Rectangle(nodeleft -
checkboxwidth - checknodespace, top + (height - checkboxwidth) / 2,
checkboxwidth, checkboxwidth), ButtonState.Normal);
      }
      // erase the previous node text
      using (Brush b = new SolidBrush(BackColor))
      {
        e.Graphics.DrawString(e.Node.Text,Font, b, nodeleft, nodetop);
      }
      // draw node text and highlight rectangle
      if (e.Node.IsSelected)
      {
        ControlPaint.DrawFocusRectangle(e.Graphics, e.Node.Bounds);

        e.Graphics.FillRectangle(Brushes.LightSkyBlue, new
Rectangle(nodeleft + 1, nodetop + 1, nodewidth - 2, nodeheight - 2));
        using (Brush b = new SolidBrush(Color.White))
        {
            e.Graphics.DrawString(e.Node.Text, Font, b, nodeleft, nodetop);
        }
      }
      else
      {
        using (Brush b = new SolidBrush(ForeColor))
        {
            e.Graphics.DrawString(e.Node.Text, Font, b, nodeleft, nodetop);
        }
      }
    }

  }
}

File: form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace TreeViewErrorVista
{
  public partial class Form1 : Form
  {
    public Form1()
    {
      InitializeComponent();
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
      if (treeViewVista1.Nodes[0].Checked)
      {
        lbtreeViewVista1.Text = "Checked";
      }
      else
      {
        lbtreeViewVista1.Text = "Not checked";
      }

      if (treeView1.Nodes[0].Checked)
      {
        lbtreeView1.Text = "Checked";
      }
      else
      {
        lbtreeView1.Text = "Not checked";
      }

      if (treeViewVista2.Nodes[0].Checked)
      {
        lbtreeViewVista2.Text = "Checked";
      }
      else
      {
        lbtreeViewVista2.Text = "Not checked";
      }

      if (treeView2.Nodes[0].Checked)
      {
        lbtreeView2.Text = "Checked";
      }
      else
      {
        lbtreeView2.Text = "Not checked";
      }

    }

    private void Form1_Load(object sender, EventArgs e)
    {

      foreach (TreeView tv in new TreeView[] { treeView1, treeView2,
treeViewVista1, treeViewVista2 })
      {
        TreeNode myNode = new TreeNode("TestNode", 0, 0);
        tv.Nodes.Add(myNode);
        myNode.Nodes.Add("SubNode2");
        myNode.Nodes.Add("SubNode3");
        tv.Nodes.Add(new TreeNode("TestNode2", 0, 0));
        tv.Nodes.Add(new TreeNode("TestNode3", 0, 0));
      }
    }

  }
}

>
> If you have any question, please feel free to let me know.
>
> Sincerely,
> Linda Liu
> Microsoft Online Community Support
>

Sincerely.
Dieter Pelz
Author
16 Nov 2007 11:12 AM
Linda Liu[MSFT]
Hi Dieter,

Thank you for feedback!

I understand your concern and I will forward your concern to our product
team.

As for the workaround of custom drawing the TreeView by ourselves, I must
say that it may be difficult to make the custom drawn TreeView look exactly
the same as the standard TreeView, because the TreeView has so many
properties that would influence the appearance and behavior of it. But we
can do our best to make the custom drawn TreeView look more like a standard
TreeView.

The following is the modified code of the custom drawn TreeView:

using System;
using System.Windows.Forms;
using System.Drawing;
using System.Windows.Forms.VisualStyles;

public class TreeViewVista : TreeView
  {
      public TreeViewVista()
      {
          if (Environment.OSVersion.Version.Major >= 6)
          {
              DrawMode = TreeViewDrawMode.OwnerDrawAll;
              DrawNode += new DrawTreeNodeEventHandler(treeView1_DrawNode);
          }         
      }

      int linelength = 0;
      private void treeView1_DrawNode(object sender, DrawTreeNodeEventArgs
e)
      {         
          int left = e.Bounds.X;
          int top = e.Bounds.Y;
          int height = e.Bounds.Height;
          int nodeleft = e.Node.Bounds.X;
          int nodetop = e.Node.Bounds.Y;
          int nodeheight = e.Node.Bounds.Height;
          int nodewidth = e.Node.Bounds.Width;        
          int checkboxwidth = 13;
          int checknodespace = 2;
          if (e.Node.Level == 0 && e.Node.Index == 0)
          {
              linelength = nodeleft - checknodespace - checkboxwidth - left;
              if (this.ImageList != null)
              {
                  linelength -= this.ImageList.ImageSize.Width;
              }
              linelength = linelength / 2;
          }         

          int lineleft = nodeleft - checknodespace - checkboxwidth -
linelength;
          if (this.ImageList != null)
          {
              lineleft -= this.ImageList.ImageSize.Width;
          }

          using (Pen p = new Pen(Color.Gray))
          {
              p.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;

              //draw horizontal dot line
              e.Graphics.DrawLine(p, lineleft, top + height / 2, lineleft +
linelength, top + height / 2);
              // draw the up half vertical dot line
              if (e.Node.PrevNode != null || e.Node.Parent != null)
              {
                  e.Graphics.DrawLine(p, lineleft, top, lineleft, top +
height / 2);
              }
              // draw the down half vertical dot line
              if (e.Node.NextNode != null)
              {
                  e.Graphics.DrawLine(p, lineleft, top + height / 2,
                    lineleft, e.Node.NextNode.Bounds.Top);
              }
              // draw plus/minus image
              if (e.Node.Nodes.Count > 0)
              {
                  if (!e.Node.IsExpanded)
                  {
                      e.Graphics.DrawImage(Properties.Resources.plus,
                        lineleft - Properties.Resources.plus.Width / 2, top
+ (height -
                        Properties.Resources.plus.Height) / 2);
                  }
                  else
                  {
                      e.Graphics.DrawImage(Properties.Resources.minus,
                        lineleft - Properties.Resources.minus.Width / 2,
top + (height -
                        Properties.Resources.minus.Height) / 2);
                  }
              }
              // draw the vertical dot line for the parent nodes if
necessary
              TreeNode parentNode = e.Node.Parent;
              int parentNodeLeftDistance = checknodespace + checkboxwidth +
linelength;
              if (this.ImageList != null)
              {
                  parentNodeLeftDistance += this.ImageList.ImageSize.Width;
              }
              while (parentNode != null)
              {
                  if (parentNode.NextNode != null)
                  {
                      e.Graphics.DrawLine(p, parentNode.Bounds.X -
parentNodeLeftDistance,
                        top, parentNode.Bounds.X - parentNodeLeftDistance,
top + height);
                  }
                  parentNode = parentNode.Parent;
              }
          }
          // draw checkbox
          if (e.Node.Checked)
          {             
              CheckBoxRenderer.DrawCheckBox(e.Graphics, new Point(lineleft
+ linelength,
                  top + (height - checkboxwidth) / 2),
CheckBoxState.CheckedNormal);
          }
          else
          {
              CheckBoxRenderer.DrawCheckBox(e.Graphics, new Point(lineleft
+ linelength,
               top + (height - checkboxwidth) / 2),
CheckBoxState.UncheckedNormal);
          }

          // draw image if any
          if (this.ImageList != null && e.Node.ImageIndex >= 0)
          {

e.Graphics.DrawImage(this.ImageList.Images[e.Node.ImageIndex], new
Rectangle(lineleft + linelength + checkboxwidth, top -
(this.ImageList.ImageSize.Height - height) / 2,
this.ImageList.ImageSize.Width, this.ImageList.ImageSize.Height));
          }
          // erase the previous node text and highlight background
          using (Brush b = new SolidBrush(BackColor))
          {
              e.Graphics.DrawString(e.Node.Text, Font, b, nodeleft, nodetop
+ (nodeheight - this.Font.Height) / 2);
              e.Graphics.FillRectangle(b, new Rectangle(nodeleft + 1,
nodetop + 1, nodewidth - 2, nodeheight - 2));
          }
          // draw node text
          if (this.Focused && e.Node.IsSelected)
          {
              // draw highlight background
              e.Graphics.FillRectangle(SystemBrushes.Highlight, new
Rectangle(nodeleft + 1, nodetop + 1, nodewidth - 2, nodeheight - 2));
          }
          else if (!this.Focused && !this.HideSelection &&
e.Node.IsSelected)
          {
              // draw gray background
              e.Graphics.FillRectangle(SystemBrushes.ControlLight, new
Rectangle(nodeleft + 1, nodetop + 1, nodewidth - 2, nodeheight - 2));
          }
          // draw highlight rectangle 
          if (e.Node.IsSelected && this.Focused)
          {             
              using (Brush b = new SolidBrush(Color.White))
              {
                  e.Graphics.DrawString(e.Node.Text, Font, b, nodeleft,
nodetop + (nodeheight - this.Font.Height) / 2);
              }
          }
          else
          {
              using (Brush b = new SolidBrush(ForeColor))
              {
                  e.Graphics.DrawString(e.Node.Text, Font, b, nodeleft,
nodetop + (nodeheight - this.Font.Height) / 2);
              }
          }

      }
  }
Please try the above code in your project to see if there's any problem in
it and let me know the result.

Sincerely,
Linda Liu
Microsoft Online Community Support
Author
21 Nov 2007 11:09 AM
Linda Liu[MSFT]
Hi Dieter,

I have forwarded your concern to our product team.

How about the modified sample I gave you in my previous reply? Is there any
problem?

If you have any question, please feel free to let me know.

Sincerely,
Linda Liu
Microsoft Online Community Support
Author
26 Nov 2007 11:40 AM
Dieter Pelz
Hallo Linda,

thanks for your sample.

I changed the recognition of the ImageList entry and now is looks like
nearly the same.

How could I recognize if Visual Styles are enable to switch on the OwnerDraw
function only with visual styles?

I recognized a 1 Pixel difference in horizontal axis between the OwnerDraw
function an the real function. This could be a dependency on the bitmaps for
plus and minus. What size must they have?

Thanks,
Dieter Pelz

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
using System.Drawing;

namespace TreeViewErrorVista
{
  public class TreeViewVista : TreeView
  {
      public TreeViewVista()
      {
          if (Environment.OSVersion.Version.Major >= 6)
          {
              DrawMode = TreeViewDrawMode.OwnerDrawAll;
              DrawNode += new DrawTreeNodeEventHandler(treeView1_DrawNode);
          }
      }

      int linelength = 0;
      private void treeView1_DrawNode(object sender, DrawTreeNodeEventArgs
e)
      {
          int left = e.Bounds.X;
          int top = e.Bounds.Y;
          int height = e.Bounds.Height;
          int nodeleft = e.Node.Bounds.X;
          int nodetop = e.Node.Bounds.Y;
          int nodeheight = e.Node.Bounds.Height;
          int nodewidth = e.Node.Bounds.Width;
          int checkboxwidth = 13;
          int checknodespace = 2;
          if (e.Node.Level == 0 && e.Node.Index == 0)
          {
              linelength = nodeleft - checknodespace - checkboxwidth - left;
              if (this.ImageList != null)
              {
                  linelength -= this.ImageList.ImageSize.Width;
              }
              linelength = linelength / 2;
          }

          int lineleft = nodeleft - checknodespace - checkboxwidth -
linelength;
          if (this.ImageList != null)
          {
              lineleft -= this.ImageList.ImageSize.Width;
          }

          using (Pen p = new Pen(Color.Gray))
          {
              p.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;

              //draw horizontal dot line
              e.Graphics.DrawLine(p, lineleft, top + height / 2, lineleft +
linelength, top + height / 2);
              // draw the up half vertical dot line
              if (e.Node.PrevNode != null || e.Node.Parent != null)
              {
                  e.Graphics.DrawLine(p, lineleft, top, lineleft, top +
height / 2);
              }
              // draw the down half vertical dot line
              if (e.Node.NextNode != null)
              {
                  e.Graphics.DrawLine(p, lineleft, top + height / 2,
                    lineleft, e.Node.NextNode.Bounds.Top);
              }
              // draw plus/minus image
              if (e.Node.Nodes.Count > 0)
              {
                  if (!e.Node.IsExpanded)
                  {
                      e.Graphics.DrawImage(Properties.Resources.plus,
lineleft - Properties.Resources.plus.Width / 2, top + (height -
                        Properties.Resources.plus.Height) / 2);
                  }
                  else
                  {
                      e.Graphics.DrawImage(Properties.Resources.minus,
                        lineleft - Properties.Resources.minus.Width / 2, top
+ (height - Properties.Resources.minus.Height) / 2);
                  }
              }
              // draw the vertical dot line for the parent nodes if
necessary
              TreeNode parentNode = e.Node.Parent;
              int parentNodeLeftDistance = checknodespace + checkboxwidth +
linelength;
              if (this.ImageList != null)
              {
                  parentNodeLeftDistance += this.ImageList.ImageSize.Width;
              }
              while (parentNode != null)
              {
                  if (parentNode.NextNode != null)
                  {
                      e.Graphics.DrawLine(p, parentNode.Bounds.X -
parentNodeLeftDistance,
                        top, parentNode.Bounds.X - parentNodeLeftDistance,
top + height);
                  }
                  parentNode = parentNode.Parent;
              }
          }
          // draw checkbox
          if (e.Node.Checked)
          {
              CheckBoxRenderer.DrawCheckBox(e.Graphics, new Point(lineleft +
linelength,
                  top + (height - checkboxwidth) / 2),
CheckBoxState.CheckedNormal);
          }
          else
          {
              CheckBoxRenderer.DrawCheckBox(e.Graphics, new Point(lineleft +
linelength,
               top + (height - checkboxwidth) / 2),
CheckBoxState.UncheckedNormal);
          }

          // draw image if any
//          if (this.ImageList != null && e.Node.ImageIndex >= 0)
          if (this.ImageList != null)
          {
            int imageIndex = e.Node.ImageIndex;
            if (e.Node.ImageIndex < 0)
              imageIndex = 0;

            e.Graphics.DrawImage(this.ImageList.Images[imageIndex],
              new Rectangle(lineleft + linelength + checkboxwidth, top -
(this.ImageList.ImageSize.Height - height) / 2,
                            this.ImageList.ImageSize.Width,
this.ImageList.ImageSize.Height));
          }
          // erase the previous node text and highlight background
          using (Brush b = new SolidBrush(BackColor))
          {
              e.Graphics.DrawString(e.Node.Text, Font, b, nodeleft, nodetop
+ (nodeheight - this.Font.Height) / 2);
              e.Graphics.FillRectangle(b, new Rectangle(nodeleft + 1,
nodetop + 1, nodewidth - 2, nodeheight - 2));
          }
          // draw node text
          if (this.Focused && e.Node.IsSelected)
          {
              // draw highlight background
              e.Graphics.FillRectangle(SystemBrushes.Highlight, new
Rectangle(nodeleft + 1, nodetop + 1, nodewidth - 2, nodeheight - 2));
          }
          else if (!this.Focused && !this.HideSelection &&
e.Node.IsSelected)
          {
              // draw gray background
              e.Graphics.FillRectangle(SystemBrushes.ControlLight, new
Rectangle(nodeleft + 1, nodetop + 1, nodewidth - 2, nodeheight - 2));
          }
          // draw highlight rectangle
          if (e.Node.IsSelected && this.Focused)
          {
              using (Brush b = new SolidBrush(Color.White))
              {
                  e.Graphics.DrawString(e.Node.Text, Font, b, nodeleft,
nodetop + (nodeheight - this.Font.Height) / 2);
              }
          }
          else
          {
              using (Brush b = new SolidBrush(ForeColor))
              {
                  e.Graphics.DrawString(e.Node.Text, Font, b, nodeleft,
nodetop + (nodeheight - this.Font.Height) / 2);
              }
          }

      }
  }

}





Show quote
"Linda Liu[MSFT]" <v-l***@online.microsoft.com> schrieb im Newsbeitrag
news:I9VhJ8CLIHA.5204@TK2MSFTNGHUB02.phx.gbl...
> Hi Dieter,
>
> I have forwarded your concern to our product team.
>
> How about the modified sample I gave you in my previous reply? Is there
> any
> problem?
>
> If you have any question, please feel free to let me know.
>
> Sincerely,
> Linda Liu
> Microsoft Online Community Support
>
Author
27 Nov 2007 3:23 AM
Linda Liu[MSFT]
Hi Dieter,

Thank you for your feedback!

> How could I recognize if Visual Styles are enable to switch on the
OwnerDraw function only with visual styles?

You can use the Application.RenderWithVisualStyles property to recognize if
Visual Styles are enabled.

> I recognized a 1 Pixel difference in horizontal axis between the
OwnerDraw function an the real function. This could be a dependency on the
bitmaps for plus and minus. What size must they have?

Do you mean the size of the bitmaps for the plus and minus? In my sample
project, I set both the width and height of the two bitmaps to 9.

I made a small modification in the custom draw TreeView to ensure that the
TreeView control is custom drawn only when the CheckBox property is true
and the OS version is Vista and Visual Styles is enabled.

In addition, I implemented the ISupportInitialize interface in the derived
TreeView class so as to set DrawMode property to OwnerDrawAll when the
above condition is met at run time.

FYI, I use the Control.DesignMode property to recognize whether a control
is at design time. However, it's too early to use this property in the
constructor because the DesignMode property relies on the Site property(the
Site property is set by the designer, if the Site property is not null, the
DesignMode property returns true; otherwise, the DesignMode returns false)
and the key point is that the control has not finished the construction in
the constructor so the Site property has not been set and the DesignMode
always returns false.

In the other hand, if a control implements the ISupportInitialize
interface, the ISupportInitialize.BeginEdit and ISupportInitialize.EndEdit
methods will be serialized in the InitializeComponent method of a form when
we drag&drop this control onto a form.

Note that both the ISupportInitialize.BeginEdit and the
ISupportInitialize.EndEdit method are serialized after the control is
created, so we can use the DesignMode property  to recognize if the control
is at design time within either the ISupportInitialize.BeginEdit method or
the ISupportInitialize.EndEdit method.

I will send my modified sample project to your email address. If there's
any question in the sample project, please feel free to let me know.

Sincerely,
Linda Liu
Microsoft Online Community Support
Author
27 Nov 2007 9:52 AM
Dieter Pelz
Hi Linda,

thanks for your answer.

I change the rectangle around the text to the original boundings and now the
recttangle around the text ist ok.

The only thing in the geometry that is not chown like the original is an 1
pixel offset.
See the attached png.

What must be change to figure this out?

The other things what about the colors?
The Color.White is used selected and focused nodes. Is this the right Color,
or is there an system color?

The Brush SystemBrushes.ControlLight seemed not to be the right color, see
the attached image.

Thanks,
Dieter Pelz

using System;
using System.Windows.Forms;
using System.Drawing;
using System.Windows.Forms.VisualStyles;
using System.ComponentModel;

namespace TreeViewErrorVista
{
  public class TreeViewVista : TreeView,ISupportInitialize
  {
      #region ISupportInitialize Members

      void ISupportInitialize.BeginInit()
      {

      }

      void ISupportInitialize.EndInit()
      {
          if (!this.DesignMode)
          {
              if (this.CheckBoxes && Environment.OSVersion.Version.Major >=
6 && Application.RenderWithVisualStyles)
              {
                  DrawMode = TreeViewDrawMode.OwnerDrawAll;
                  DrawNode += new
DrawTreeNodeEventHandler(treeView1_DrawNode);
              }
          }
      }

      #endregion

      int linelength = 0;
      private void treeView1_DrawNode(object sender, DrawTreeNodeEventArgs
e)
      {
          int left = e.Bounds.X;
          int top = e.Bounds.Y;
          int height = e.Bounds.Height;
          int nodeleft = e.Node.Bounds.X;
          int nodetop = e.Node.Bounds.Y;
          int nodeheight = e.Node.Bounds.Height;
          int nodewidth = e.Node.Bounds.Width;
          int checkboxwidth = 13;
          int checknodespace = 2;
          if (e.Node.Level == 0 && e.Node.Index == 0)
          {
              linelength = nodeleft - checknodespace - checkboxwidth - left;
              if (this.ImageList != null)
              {
                  linelength -= this.ImageList.ImageSize.Width;
              }
              linelength = linelength / 2;
          }

          int lineleft = nodeleft - checknodespace - checkboxwidth -
linelength;
          if (this.ImageList != null)
          {
              lineleft -= this.ImageList.ImageSize.Width;
          }

          using (Pen p = new Pen(Color.Gray))
          {
              p.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;

              //draw horizontal dot line
              e.Graphics.DrawLine(p, lineleft, top + height / 2, lineleft +
linelength, top + height / 2);
              // draw the up half vertical dot line
              if (e.Node.PrevNode != null || e.Node.Parent != null)
              {
                  e.Graphics.DrawLine(p, lineleft, top, lineleft, top +
height / 2);
              }
              // draw the down half vertical dot line
              if (e.Node.NextNode != null)
              {
                  e.Graphics.DrawLine(p, lineleft, top + height / 2,
                    lineleft, e.Node.NextNode.Bounds.Top);
              }
              // draw plus/minus image
              if (e.Node.Nodes.Count > 0)
              {
                  if (!e.Node.IsExpanded)
                  {
                      e.Graphics.DrawImage(Properties.Resources.plus,
                        lineleft - Properties.Resources.plus.Width / 2, top
+ (height -
                        Properties.Resources.plus.Height) / 2);
                  }
                  else
                  {
                      e.Graphics.DrawImage(Properties.Resources.minus,
                        lineleft - Properties.Resources.minus.Width / 2, top
+ (height -
                        Properties.Resources.minus.Height) / 2);
                  }
              }
              // draw the vertical dot line for the parent nodes if
necessary
              TreeNode parentNode = e.Node.Parent;
              int parentNodeLeftDistance = checknodespace + checkboxwidth +
linelength;
              if (this.ImageList != null)
              {
                  parentNodeLeftDistance += this.ImageList.ImageSize.Width;
              }
              while (parentNode != null)
              {
                  if (parentNode.NextNode != null)
                  {
                      e.Graphics.DrawLine(p, parentNode.Bounds.X -
parentNodeLeftDistance,
                        top, parentNode.Bounds.X - parentNodeLeftDistance,
top + height);
                  }
                  parentNode = parentNode.Parent;
              }
          }
          // draw checkbox
          if (e.Node.Checked)
          {
              CheckBoxRenderer.DrawCheckBox(e.Graphics, new Point(lineleft +
linelength,
                  top + (height - checkboxwidth) / 2),
CheckBoxState.CheckedNormal);
          }
          else
          {
              CheckBoxRenderer.DrawCheckBox(e.Graphics, new Point(lineleft +
linelength,
               top + (height - checkboxwidth) / 2),
CheckBoxState.UncheckedNormal);
          }

          // draw image if any
          //if (this.ImageList != null && this.ImageList.Images.Count > 0 &&
e.Node.ImageIndex >= 0)
          //{
          //
e.Graphics.DrawImage(this.ImageList.Images[e.Node.ImageIndex], new
Rectangle(lineleft + linelength + checkboxwidth, top -
(this.ImageList.ImageSize.Height - height) / 2,
this.ImageList.ImageSize.Width, this.ImageList.ImageSize.Height));
          //}
          if (this.ImageList != null)
          {
              int imageIndex = e.Node.ImageIndex;
              if (e.Node.ImageIndex < 0)
                  imageIndex = 0;

              e.Graphics.DrawImage(this.ImageList.Images[imageIndex],
                new Rectangle(lineleft + linelength + checkboxwidth, top -
(this.ImageList.ImageSize.Height - height) / 2,
                              this.ImageList.ImageSize.Width,
this.ImageList.ImageSize.Height));
          }
          // erase the previous node text and highlight background
          using (Brush b = new SolidBrush(BackColor))
          {
              e.Graphics.DrawString(e.Node.Text, Font, b, nodeleft, nodetop
+ (nodeheight - this.Font.Height) / 2);
              e.Graphics.FillRectangle(b, new Rectangle(nodeleft, nodetop,
nodewidth, nodeheight));
          }
          // draw background
          if (this.Focused && e.Node.IsSelected)
          {
              // draw highlight background
              e.Graphics.FillRectangle(SystemBrushes.Highlight, new
Rectangle(nodeleft, nodetop, nodewidth, nodeheight));
          }
          else if (!this.Focused && !this.HideSelection &&
e.Node.IsSelected)
          {
              // draw gray background
              e.Graphics.FillRectangle(SystemBrushes.ControlLight, new
Rectangle(nodeleft, nodetop, nodewidth, nodeheight));
          }
          // draw highlight node text
          if (e.Node.IsSelected && this.Focused)
          {
              using (Brush b = new SolidBrush(Color.White))
              {
                  e.Graphics.DrawString(e.Node.Text, Font, b, nodeleft,
nodetop + (nodeheight - this.Font.Height) / 2);
              }
          }
          else
          {
              using (Brush b = new SolidBrush(ForeColor))
              {
                  e.Graphics.DrawString(e.Node.Text, Font, b, nodeleft,
nodetop + (nodeheight - this.Font.Height) / 2);
              }
          }

      }


  }
}



Show quote
"Linda Liu[MSFT]" <v-l***@online.microsoft.com> schrieb im Newsbeitrag
news:wUfZxTKMIHA.4380@TK2MSFTNGHUB02.phx.gbl...
> Hi Dieter,
>
> Thank you for your feedback!
>
>> How could I recognize if Visual Styles are enable to switch on the
> OwnerDraw function only with visual styles?
>
> You can use the Application.RenderWithVisualStyles property to recognize
> if
> Visual Styles are enabled.
>
>> I recognized a 1 Pixel difference in horizontal axis between the
> OwnerDraw function an the real function. This could be a dependency on the
> bitmaps for plus and minus. What size must they have?
>
> Do you mean the size of the bitmaps for the plus and minus? In my sample
> project, I set both the width and height of the two bitmaps to 9.
>
> I made a small modification in the custom draw TreeView to ensure that the
> TreeView control is custom drawn only when the CheckBox property is true
> and the OS version is Vista and Visual Styles is enabled.
>
> In addition, I implemented the ISupportInitialize interface in the derived
> TreeView class so as to set DrawMode property to OwnerDrawAll when the
> above condition is met at run time.
>
> FYI, I use the Control.DesignMode property to recognize whether a control
> is at design time. However, it's too early to use this property in the
> constructor because the DesignMode property relies on the Site
> property(the
> Site property is set by the designer, if the Site property is not null,
> the
> DesignMode property returns true; otherwise, the DesignMode returns false)
> and the key point is that the control has not finished the construction in
> the constructor so the Site property has not been set and the DesignMode
> always returns false.
>
> In the other hand, if a control implements the ISupportInitialize
> interface, the ISupportInitialize.BeginEdit and ISupportInitialize.EndEdit
> methods will be serialized in the InitializeComponent method of a form
> when
> we drag&drop this control onto a form.
>
> Note that both the ISupportInitialize.BeginEdit and the
> ISupportInitialize.EndEdit method are serialized after the control is
> created, so we can use the DesignMode property  to recognize if the
> control
> is at design time within either the ISupportInitialize.BeginEdit method or
> the ISupportInitialize.EndEdit method.
>
> I will send my modified sample project to your email address. If there's
> any question in the sample project, please feel free to let me know.
>
> Sincerely,
> Linda Liu
> Microsoft Online Community Support
>
Author
29 Nov 2007 7:06 AM
Linda Liu[MSFT]
Hi Dieter,

Thank you for your reply!

> The only thing in the geometry that is not chown like the original is an
1 pixel offset. What must be change to figure this out?

Actually, I calculate the location of each element such as checkbox, image
and horizontal line based on some assumptions, e.g. the distance between
the checkbox and the node text is 2 pixels and the horizontal line starts
form the half of the bound left and checkbox. Obviously, it may not very
accurate.

We can adjust the value of the local variable 'checknodespace' defined in
derived TreeView's DrawNode event handler to 3. In addition, I find that if
the TreeView doesn't have a image list, the distance between checkbox and
the node text seems to be 0.

So we can modify the sample code as follows to figure this problem out:

private void treeView1_DrawNode(object sender, DrawTreeNodeEventArgs e)
{
      ....
      int checknodespace = 0;
      if (this.ImageList != null)
      {
              checknodespace = 3;
      }
      ....
}

> The Color.White is used selected and focused nodes. Is this the right
Color, or is there an system color?

I find a system color called HightlightText, which is just the right color
for selected and focused nodes.

> The Brush SystemBrushes.ControlLight seemed not to be the right color

I agree with you. Unfortunately, I don't find the exactly same color as the
one used in the standard TreeView. IMO, the color of ControlLight is the
most similar one.

If you have any question, please feel free to let me know.

Sincerely,
Linda Liu
Microsoft Online Community Support

AddThis Social Bookmark Button