locked
Treeview, on mouse click highlight the node with different color. RRS feed

  • Question

  • Hi,

    I am working on WM6.0 application which has a TreeView control. By default whenever we click on any tree node using mouse it is highlighted by some system color (for WM6.0 its green). How can i change this highlighting color?

    Thank you in advance

    Tuesday, October 18, 2011 9:16 AM

Answers

All replies

  • You can send a TVM_SETLINECOLOR message to the control.

    -PaulH

    Tuesday, October 18, 2011 5:25 PM
  • Thanks Paul,

    I tried importing coredll in my C# application and calling the SendMessage API as below

    [DllImport("coredll.dll")]
    public static extern int SendMessage(IntPtr hwnd, uint msg, uint wParam, uint lParam);

     

    public const uint CLR_MAGENTA = 0xFF00FF;

    public const uint TVM_SETLINECOLOR = TV_FIRST + 40;


    SendMessage(this.Handle, TVM_SETLINECOLOR, 0, CLR_MAGENTA);

    But this did not set the colour. Please can u guide me?

    Thank you


    -pavya
    • Edited by snooze1907 Thursday, October 20, 2011 11:25 AM
    Thursday, October 20, 2011 11:24 AM
  • Sorry, I misunderstood your question. That command would set the color of the tree lines connecting nodes. You will need to put the treeview in owner draw mode.

     

    Put the tree in to owner draw text mode:

    myTreeView.DrawMode = TreeViewDrawMode.OwnerDrawText;
    myTreeView.DrawNode += 
                new DrawTreeNodeEventHandler(myTreeView_DrawNode);
    

     

    Then, in your DrawNode handler, draw the highlight in the color you want:

        private void myTreeView_DrawNode(
            object sender, DrawTreeNodeEventArgs e)
        {
            // Draw the background and node text for a selected node.
            if ((e.State & TreeNodeStates.Selected) != 0)
            {
                // Draw the background of the selected node. The NodeBounds
                // method makes the highlight rectangle large enough to
                // include the text of a node tag, if one is present.
                e.Graphics.FillRectangle(Brushes.Green, NodeBounds(e.Node));
    
                // ...
            }
            // ...
        }
    

    There is an example on the MSDN page:

    http://msdn.microsoft.com/en-us/library/system.windows.forms.treeview.drawnode.aspx

    -PaulH

    Thursday, October 20, 2011 7:20 PM
  • But we dont have this event in .net compact frame work rite?

    I want it for WM 6.0 application. If you hav any examples for the same please share it.
    I tried changing the back color of node on AfterSelect event, this changes the color of previously selected node once you select new node. But the current selected node which is highlighted is still in some sytem color (green for WM 6.0).


    -pavya
    Friday, October 21, 2011 4:42 AM
  • Hello,

     

    As far as I know, that color is system color, you can call SetSysColors or GetSysColor to change the COLOR_HIGHLIGHT value. In this way, all the system color will be changed, so you need set the system color back, when you clos the form. You can P/Invoke these functions in this way:

     

            //declaring
            [DllImport("coredll.dll", SetLastError = true)]
            private static extern bool SetSysColors(int cElements, Int32[] lpaElements, Int32[] lpaRgbValues);
    
            [DllImport("coredll.dll", SetLastError = true)]
            private static extern uint GetSysColor(int nIndex);
    
            private const int SYS_COLOR_INDEX_FLAG = 0x40000000;
            public const int COLOR_HIGHLIGHT = (13 | SYS_COLOR_INDEX_FLAG);
    
    
    
                //set system color
                uint old_color = GetSysColor(COLOR_HIGHLIGHT);
                int[] lpaElements={COLOR_HIGHLIGHT};
                //I found that the r value and the blue value is contrary in mobile
                int[] lpaRgbValues = { Color.Red.ToArgb() & 0x00ffffff };
                bool res = SetSysColors(1, lpaElements, lpaRgbValues);
                if (!res)
                {
                    int error = Marshal.GetLastWin32Error();
                    throw new Exception(string.Format("SetSysColors() returned {0}!", error));
                }
    
    
    
                //reset the color back
                lpaRgbValues[0] = (int)old_color;
                SetSysColors(1, lpaElements, lpaRgbValues);
    

    I hope these information can help you to solve this problem.

     

    Best regards,

    Jesse


    Jesse Jiang [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Friday, October 21, 2011 6:31 AM
  • Thanks Jesse,

    This works, but can this can be done for particular control (like list or tree view) alone instead of doing it for system?

    Regards


    -pavya
    Monday, October 24, 2011 7:01 AM
  • It will be difficult, because this color is get from the API. We cannot change the source codes of that control, so that we can only change the system color.

     

    Another solution is you can write a tree view by yourself.

     

    Best regards,

    Jesse


    Jesse Jiang [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Monday, October 24, 2011 7:39 AM
  • Can i get any sample code with minimum functionality to implement my own customized tree? Or else any links which would guide me to implement?

    Thanks & Regards,

    Praveen


    -pavya
    Monday, October 24, 2011 8:50 AM
  • If owner drawing isn't implemented in the CF, you can always p/invoke the native functions to do it (though it will be more challenging)

    You will need to override the control's WinProc

    WM_USER = 0x0400
    WM_NOTIFY = 0x004E
    WM_REFLECT = WM_USER + 0x1C00
    
    protected override void WndProc(ref Message m)
    {
        switch (m.Msn) {
            case WM_REFLECT + WM_NOTIFY:
                ... process notification messages
            break;
        }
    }
    

    See Developing Custom Draw Controls in Visual C++.

    The article covers listview, but the concept is the same for treeview.

     

    Another example showing a double-buffering technique with an owner draw treeview.

    -PaulH

     

    • Proposed as answer by Jesse Jiang Wednesday, October 26, 2011 7:46 AM
    • Marked as answer by snooze1907 Monday, October 31, 2011 8:45 AM
    Monday, October 24, 2011 3:34 PM
  • Hello,

     

    Would you please post the worked codes here, so that other person meets the same problem will get help from here.

     

    Best regards,

    Jesse


    Jesse Jiang [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Monday, October 31, 2011 9:03 AM