Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MenuStrip attached to tabcontrol #3

Open
albay opened this issue Apr 17, 2019 · 14 comments
Open

MenuStrip attached to tabcontrol #3

albay opened this issue Apr 17, 2019 · 14 comments

Comments

@albay
Copy link

albay commented Apr 17, 2019

Hello,

Thank you for making such a great control, it is very useful. But I would like to have a menustrip attached to it like below.

image

Is it possible to implement such thing or not worth to try? Can you give me suggestions please about how to do it?

@albay
Copy link
Author

albay commented Apr 17, 2019

I managed to attach somehow with the following codes.

image

MenuStrip _menuStrip;

public MenuStrip Menu
{
	get { return _menuStrip; }
	set {
		_menuStrip = value;

		if (_menuStrip != null)
		{
			_menuStrip.Parent = Parent;
			_menuStrip.Dock = DockStyle.None;
			_menuStrip.BringToFront();
			_menuStrip.Location = new Point(2, 2);
		}
	}
}

...

private Rectangle GetBaseTabRect(int index)
{
	var rect = GetTabRect(index);

	if(_menuStrip != null)
	{
		rect.X += _menuStrip.Location.X + _menuStrip.Size.Width;
	}
        ...
}

@rlktradewright
Copy link
Contributor

Can you please explain why you think this would be useful?

Locating a MenuStrip in the position you've shown makes it very unclear as to whether the MenuStrip somehow relates to the TabControl as a whole ,,or to a particular TabPage in the TabControl, or to something else. In other words, I think this would be unsatisfactory design.

@albay
Copy link
Author

albay commented Apr 17, 2019

I would like to use it on a borderless window like following tool does.

image

I think it does make sense now.

@rlktradewright
Copy link
Contributor

Sorry for the delay in getting back to you. I'm in the UK, and it was getting rather late last night.

Having had time to think about this a bit, and with your illustrations in mind, I think I see a way forward that would give you what you want, but also be much more flexible.

I suggest a new int property, TabOffset, that specifies where the first tab starts relative to the left edge of the control (or the top edge for vertical tabs). Another new property, ControlPanel, returns a Panel control that fills the space vacated by the offset: the panel's width would be the same as the offset, and its height would be the same as the tab height; by default its backcolor would be transparent, but the application could change this. The application would be prevented from changing the size or location of the panel, other than through the TabOffset property.

With this arrangement, the application can reserve whatever space it needs for additional controls (eg a ContextMenuStrip), and then add the control(s) to the ControlPanel. The tab control itself need know nothing about the types or number of controls added.

I can't guarantee at this stage that I'll be able to make this work properly: initial work shows that fiddling with the tab positions doesn't appear to cause a problem, but it's early days and it might turn out to be problematic.

@rlktradewright
Copy link
Contributor

I've been doing more work on this and I'm quite pleased with the results so far.

But before I go any further, I need some feedback from you as to whether this is going to suit your needs (I'm pretty sure it will!).

So here's a screenshot of an example showing two controls, a combo box and a button, in the ControlPanel. Of course you can add any controls you like, but they're limited in vertical size by the tab height (though you can adjust that using the Padding property (and of course you need to leave room for the tabs themselves!).

CustomTabControl

In this case, the ControlPanel is transparent: it can be set to any colour, but transparent works best with rounded tabs at present.

Note that the controls have to be added to the ControlPanel via code: you can't do this at design time, but it's very simple. Here's the code for the example above:

private ComboBox mCombo1 = new ComboBox();
private Button mButton1 = new Button();


public Form1() {
    InitializeComponent();

    tabControlExtra1.ControlPanel.BackColor = Color.Transparent;

    tabControlExtra1.ControlPanel.Controls.Add(mCombo1);
    mCombo1.Location = new Point(2, 0);
    mCombo1.Width = 50;

    tabControlExtra1.ControlPanel.Controls.Add(mButton1);
    mButton1.UseVisualStyleBackColor = true;
    mButton1.Width = 25;
    mButton1.Height = 21;
    mButton1.Location = new Point(mCombo1.Right + 2, 0);

    tabControlExtra1.TabOffset= mButton1.Right + 2;
}

There's a lot more work to do to make sure this all works nicely with the many formatting capabilities. So before I go any further, please let me have any feedback.

@albay
Copy link
Author

albay commented Apr 19, 2019

Hello Richard,

What you are doing so far seems quite good and exceeds my expectations :)

All I need for now is to have a menustrip next to first tabPage. I am not planning to add any other control yet. With your implementation, I guess I can do it by creating a usercontrol and add to the controlpanel in one shot.

How can I check if all these things you made so far really work for me?

@rlktradewright
Copy link
Contributor

You wouldn't need to create a usercontrol. Just create the menustrip and its menu items, and add it to the ControlPanel. Here's an example:

CustomTabControl

This one was created with this code:

        private MenuStrip mMenuStrip =new MenuStrip();
        private ToolStripMenuItem mFileMenu = new ToolStripMenuItem();
        private ToolStripMenuItem mEditMenu = new ToolStripMenuItem();
        private ToolStripMenuItem mViewMenu = new ToolStripMenuItem();
        private ToolStripMenuItem mNewMenuItem = new ToolStripMenuItem();
        private ToolStripMenuItem mOpenMenuItem = new ToolStripMenuItem();
        private ToolStripMenuItem mExitMenuItem = new ToolStripMenuItem();


        public Form1() {
            InitializeComponent();

            tabControlExtra1.ControlPanel.BackColor = Color.Transparent;

            tabControlExtra1.ControlPanel.Controls.Add(mMenuStrip);
            mMenuStrip.Location = new Point(0, 0);
            tabControlExtra1.TabOffset = 135;


            mMenuStrip.SuspendLayout();

            mMenuStrip.Items.AddRange(new ToolStripItem[] {
                mFileMenu,
                mEditMenu,
                mViewMenu
            });
            mMenuStrip.TabIndex = 0;

            mFileMenu.DropDownItems.AddRange(new ToolStripItem[] {
                mNewMenuItem,
                mOpenMenuItem,
                mExitMenuItem
            });
            mFileMenu.Text = "File";
            mEditMenu.Text = "Edit";
            mViewMenu.Text = "View";

            mNewMenuItem.Text = "New";
            mOpenMenuItem.Text = "Open...";
            mExitMenuItem.Text = "Exit";

            mMenuStrip.ResumeLayout(false);
            mMenuStrip.PerformLayout();
        }

@rlktradewright
Copy link
Contributor

Oh, in answer to how you can check whether it all works, I just need to do a bit more work and then I can commit the changes I've made so far and you can build it and test it for yourself.

This is because although it displays correctly at the moment for the case of horizontal tabs at the top of the control, there are still issues with bottom tabs, vertical tabs, mouse handling, borders around tabs, etc etc. I just don't want you to waste your time discovering bugs that I already know about.

If you don't want to build it yourself I could give you a compiled form to try.

Let me know which you would prefer.

@albay
Copy link
Author

albay commented Apr 19, 2019

I really appreciate your hard work. It is OK to have issues with bottom tabs, vertical tabs since I don't think that I need those styles.

I prefer to build it myself.

@rlktradewright
Copy link
Contributor

Ok, I'll commit the changes in a new branch some time before too long. Probably not till early next week.

@albay
Copy link
Author

albay commented Apr 20, 2019

Thank you

@rlktradewright
Copy link
Contributor

I've just pushed the introduce-control-panel branch, which contains the basic mechanisms, and a simple demo app.

Note I've had to introduce this restriction: you can only see the ControlPanel when Alignment is Top or Bottom, and Multiline is false. In other cases, the ControlPanel will be created(and have controls added to it) but it will not be visible.

At the moment, mouse handling has not been fixed: so clicking on a tab won't necessarily select the right one, and hovering over a tab may highlight a different one.

It should be reasonably straightforward to fix these mouse issues, but there may be other side effects that I haven't realised yet.

I'll push new commits to this branch fairly regularly, but I can't devote a lot of time to this (and I'm by no means certain at this stage that I can get it all working well enough that I'm happy to release it).

@rlktradewright
Copy link
Contributor

@albay
Finally I think I've managed to fix all the mouse handling problems, and it all seems to work pretty well.

I'd be grateful if you can try it out and let me have any feedback.

@rlktradewright
Copy link
Contributor

@albay

Any feedback on this yet?

I'm actually considering trying an alternative implementation, because there is still one problem with the current version that I'm unable to fix because of the order in which the base TabControl does certain things. I'm planning to try this alternative in yet another branch, which I'll publish if it seems to be an improvement.

If I can't find a solution to this problem, I'll probably have to (reluctantly) give up on this enhancement, as I'm not happy to release it in its current form.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants