Вопрос

I’ve got a TableLayoutPanel and a Treeview and I would like to sync the mouseclicks with each other. The reason for this is that I want to be able to select something in my TableLayoutPanel and then it should also select something in the Treeview.

This is how it looks:

enter image description here

My first attempt works but there is some delay. I hooked up my Treeview to the NodeMouseClick event and when that event fires I Refresh() the TableLayoutPanel so the CellPaint event gets called and paints the whole row. With this approach I’m seeing some delay because the Treeview gets painted first and then the TableLayoutPanel.

When I’m using the same method but the other way around (click the TableLayoutPanel and select the corresponding node in the Treeview) I don’t get AS MUCH delay. I’m guessing this is because it takes longer to paint my rows than it takes to select a node.

I tried a different solution:

class TableControl : TableLayoutPanel
{
    TreeViewWithPaint m_TreeviewChild;

    public void AddChildControl(TreeViewWithPaint treeview)
    {
        m_TreeviewChild = treeview;
    }

    protected override void WndProc(ref Message message)
    {
        const int WM_LBUTTONDOWN = 0x201;

        switch (message.Msg)
        {
            case WM_LBUTTONDOWN:
                //invalidate our table control so the OnPaint Method gets fired
                this.Update();
                //now copy the message and send it to the treeview
                Message copy = new Message
                {
                    HWnd = m_TreeviewChild.Handle,
                    LParam = message.LParam,
                    Msg = message.Msg,
                    Result = message.Result,
                    WParam = message.WParam
                };
                //pass the message onto the linked tree view
                m_TreeviewChild.RecieveWndProc(ref copy);
                break;
        }
        base.WndProc(ref message);
    }

In my Treeview class I added this:

    public void RecieveWndProc(ref Message m)
    {
        base.WndProc(ref m);
    }

I got the idea of an example how to sync Treeview scrollbars

The problem with this is that the CellPaint event in the TableLayoutPanel isn’t getting fired anymore, even with Update()… It does however select the correct node in the Treeview:

enter image description here

I’m also foreseeing some problems with this if I try to implement the same thing in Treeview (overriding the WndProc), will this cause a crazy loop of copied messages?

So is there a(n) (easy) way to do this?

Thanks  

Это было полезно?

Решение

Solved it, instead of trying to send another click message to the TableLayoutPanel I just did all the painting in the Treeview WM_LBUTTONDOWN (I did the same for the TableLayoutPanel WM_LBUTTONDOWN message)

const int WM_LBUTTONDOWN = 0x201;

switch( message.Msg ) 
{
    case WM_LBUTTONDOWN:
        Int16 x = (Int16)message.LParam;
        Int16 y = (Int16)((int)message.LParam >> 16);

        //Getting the control at the correct position
        Control control = m_TableControl.GetControlFromPosition(0, (y / 16));

        if (control != null)
            m_TableControl.Refresh();

        TreeNode node = this.GetNodeAt(x, y);
        this.SelectedNode = node;
        break;
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top