Getting a control name/Displaying tooltip text - c#

I am developing a form with multiple options that simulates a signup form, and I want to display some tips and descriptions in a RichTextBox located by the options when the user's mouse hover by it's GroupBoxes.
Since I am fairly new to programming, I don't know if getting all the controls names one by one is the optimal, so I want to grab the controls' names inside of the tabControl control that I am using to organize everything.
private void TabControl1_MouseHover(object sender, EventArgs e)
{
foreach(Control c in this.Controls)
{
string name = c.Name;
TooltipText(name);
}
}
And I also have a method where I will write the text that will be displayed in the RichTextBox.
private string TooltipText(string name)
{
if(name == "Name:")
{
return "blabla";
}
else
{
return "none";
}
}
I've tried a generic method to show a message box if the control was detected and, as I suspected, nothing showed up:
private void TooltipText(string name)
{
if(name == "LBL_Name")
{
MessageBox.Show("hey");
return;
}
}
How can I properly detect the Groupboxes or other types of Controls inside of the TabControl control, and also display the text in the box beside it?

You don't have to create your own Tool Tips. The .net WinForms provides a ToolTip class. https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.tooltip?view=netframework-4.8
I added 2 radio buttons to a group box in design view.
Try it and see.
private void Form1_Load(object sender, EventArgs e)
{
ToolTip tip = new ToolTip();
tip.AutoPopDelay = 5000;
tip.InitialDelay = 1000;
tip.ReshowDelay = 500;
tip.SetToolTip(radioButton1, "Choose to Add Onions");
tip.SetToolTip(radioButton2, "Choose to Add Pickles");
}

Related

How I can select different text box when I am trying to fill the textbox using button control

I am trying to fill two text box in a form using button controls but it seems to work for 1 only. when I run the program, I can't select between two text box. what condition should I use?
private void Button0_Click(object sender, EventArgs e)
{
if (???????????????????)
{
metroTextBoxQuantity.Text = metroTextBoxQuantity.Text + "0";
}
else
{
metroTextBoxItemcode.Text = metroTextBoxItemcode.Text + "0";
}
}
One possible solution is to create a Control variable that stores a reference to the last clicked textbox. This would be handled by the Click event for both textboxes. Then, in your number button clicks, just append the number to the selected textbox variable. Something like this:
Control SelectedTextbox { get; set; } = null;
//Use this event handler for both the Quantity and Itemcode textbox
public TextBox_Click(object sender, EventArgs e)
{
SelectedTextbox = (Control)sender;
}
private void Button0_Click(object sender, EventArgs e)
{
if(SelectedTextbox == null)
throw new Exception("SelectedTextbox has not been set");
SelectedTextbox.Text += "0";
}
Note, if MetroTextBox doesn't inherit from Control, you'll need to change SelectedTextbox to a different type. It most likely does though.
You also may want to consider using a single event handler for all the button clicks instead of one for each. You can either parse what number button was clicked using the sender's name, or you can store the number of the button in the button's Tag and read it from there. But that's best left for another question.

How to add custom control at Run time in c#

i have one list box which has button, Textbox, Label. During runtime i will drag and drop the item from the list box, according to the selection the dynamic control will be created. (For example, If i select and drag Button from list box and drop it on the Windows Form, the button will be created). As same as i have created a CustomControl for Button. how can i add it in my list box at runtime? i mean while i drag and drop the button from the listbox the custom button should be generated. How to Do it?
Did You try this ?
var list = new ListBox();
list.Controls.Add(new Button());
If You need to dynamically create a class at runtime - take a look at this SF article How to dynamically create a class in C#?
For drag drop, you will need to set up 3 events:
A mouse down event on the list box to trigger the dragging:
private void listBox1_MouseDown(object sender, MouseEventArgs e)
{
listBox1.DoDragDrop(listBox1.SelectedItem, DragDropEffects.Copy);
}
A drag enter event on your form (or panel in this example):
private void panel1_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.Text))
{
e.Effect = DragDropEffects.Copy;
}
}
And finally the drop event on the form/panel:
private void panel1_DragDrop(object sender, DragEventArgs e)
{
Control newControl = null;
// you would really use a better design pattern to do this, but
// for demo purposes I'm using a switch statement
string selectedItem = e.Data.GetData(DataFormats.Text) as string;
switch (selectedItem)
{
case "My Custom Control":
newControl = new CustomControl();
newControl.Location = panel1.PointToClient(new Point(e.X, e.Y));
newControl.Size = new System.Drawing.Size(75, 23);
break;
}
if (newControl != null) panel1.Controls.Add(newControl);
}
For this to work you must set "AllowDrop" to true on the target form/panel.
Use #Marty's answer to add the custom control to the listbox. Override the ToString() for a better description. There are so many ways of doing it. The important part is deciding what data type the list items will be and making sure that the correct type name is used in the e.Data.GetDataPresent method. e.Data.GetFormats() can help determine what name to use.

get textbox that is in the selected tab

I have a tabcontrol with numerous tabs that all contain a textbox. How can I select the textbox that is in the currently selected tab?
I have this which captures the tabchanged event and tells me which tab is selected, but I cannot figure out how to find the textbox that is in the tab and do
textbox.Select(0, 0);
to select certain text in this textbox...
private void onTabChange(Object sender, TabControlEventArgs e)
{
}
This really sounds like a design mistake. High odds that this TextBox should not be on a tab page at all. If you want to have one text box to be present on every tab page then that's possible, Winforms makes it easy to move controls:
private void tabControl1_SelectedIndexChanged(object sender, EventArgs e) {
textBox1.Parent = tabControl1.SelectedTab;
}
If you really meant for any text box to be picked, like the first one in the tab order then:
private void tabControl1_SelectedIndexChanged(object sender, EventArgs e) {
var box = tabControl1.SelectedTab.Controls.OfType<TextBox>().Reverse().FirstOrDefault();
if (box != null) {
// etc...
}
}
Use This:
Tab TabView = (Tab)sender;
TextView txt_Tab = (TextView)TabView.FindControl("TextBoxName");
Try this:
TextBox myTB = tabControl2.SelectedTab.Controls[0] as TextBox;
myTB.Select(0, 0);
I think the following links can provide you some hints about your problem
How to access controls that are inside a TabControl tab?
and
How to get control(s) from TabPage in C#?

Why does my Tooltip not display its tip?

I have a Tooltip with the ShowAlways property set to true.
On the controls where I want the tooltip to display (LinkLabels in this instance), I see there is a "ToolTip on <name of my Tooltip>" property which expects a string.
However, my tooltip is shared between 5 LinkLabels, and should differ depending on which one is hovered over.
I do have a shared click event that works:
private void linkLabelPlatypus1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
int Platypus = 1;
LinkLabel ll = null;
if (sender is LinkLabel)
{
ll = sender as LinkLabel;
}
if (null != ll)
{
if (ll.Name == linkLabelPlatypus2.Name)
{
Platypus = 2;
} else if (ll.Name == linkLabelPlatypus3.Name)
{
Platypus = 3;
} else if (ll.Name == linkLabelPlatypus4.Name)
{
Platypus = 4;
} else if (ll.Name == linkLabelPlatypus5.Name)
{
Platypus = 5;
}
toolTipPlatypi.SetToolTip(ll, DuckbillData.GetPlatypusDataForToolTip(Platypus));
}
}
...but I want the tooltips to also show on hover, and not require the user to click the label.
You only need to set the tooltip once :
public Form1()
{
InitializeComponent();
toolTip1.SetToolTip(linkLabel1, "foo");
toolTip1.SetToolTip(linkLabel2, "bar");
}
Done.
Doing this in a MouseHover or MouseEnter handler will call this function over and over each time the event fires. It will work, but it is unnecessarily complicated.
You only need one ToolTip on a form to provide tips for any number of components and it can provide them all simultaneously and continuously (ie: you don't have to change it or set it each time). Each component can have only one tip, but you can change it throughout the program any time you like. ShowAlways does not have to be true - it is used to make tooltips show on forms which are not active (ie: hover over an inactive window behind one with focus, etc).
You should write a event handler for Mouse Hover and have your tool tip display logic inside it.
private void Label1_MouseHover(object sender, System.EventArgs e)
{
//display logic
}
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.mousehover.aspx

How can I disable a tab inside a TabControl?

Is there a way to disable a tab in a TabControl?
Cast your TabPage to a Control, then set the Enabled property to false.
((Control)this.tabPage).Enabled = false;
Therefore, the tabpage's header will still be enabled but its contents will be disabled.
The TabPage class hides the Enabled property. That was intentional as there is an awkward UI design problem with it. The basic issue is that disabling the page does not also disable the tab. And if try to work around that by disabling the tab with the Selecting event then it does not work when the TabControl has only one page.
If these usability problems do not concern you then keep in mind that the property still works, it is merely hidden from IntelliSense. If the FUD is uncomfortable then you can simply do this:
public static void EnableTab(TabPage page, bool enable) {
foreach (Control ctl in page.Controls) ctl.Enabled = enable;
}
You can simply use:
tabPage.Enabled = false;
This property is not shown, but it works without any problems.
You can program the Selecting event on TabControler to make it impossible to change to a non-editable tab:
private void tabControler_Selecting(object sender, TabControlCancelEventArgs e)
{
if (e.TabPageIndex < 0) return;
e.Cancel = !e.TabPage.Enabled;
}
You could register the "Selecting" event and cancel the navigation to the tab page:
private void tabControl1_Selecting(object sender, TabControlCancelEventArgs e)
{
if (e.TabPage == tabPage2)
e.Cancel = true;
}
Another idea is to put all the controls on the tabpage in a Panel control and disable the panel! Smiley
You could also remove the tabpage from the tabControl1.TabPages collection. That would hide the tabpage.
Credits go to littleguru # Channel 9.
Presumably, you want to see the tab in the tab control, but you want it to be "disabled" (i.e., greyed, and unselectable). There is no built-in support for this, but you can override the drawing mechanism to give the desired effect.
An example of how to do this is provided here.
The magic is in this snippet from the presented source, and in the DisableTab_DrawItem method:
this.tabControl1.DrawMode = TabDrawMode.OwnerDrawFixed;
this.tabControl1.DrawItem += new DrawItemEventHandler( DisableTab_DrawItem );
Extending upon Cédric Guillemette answer, after you disable the Control:
((Control)this.tabPage).Enabled = false;
...you may then handle the TabControl's Selecting event as:
private void tabControl_Selecting(object sender, TabControlCancelEventArgs e)
{
e.Cancel = !((Control)e.TabPage).Enabled;
}
This will remove the tab page, but you'll need to re-add it when you need it:
tabControl1.Controls.Remove(tabPage2);
If you are going to need it later, you might want to store it in a temporary tabpage before the remove and then re-add it when needed.
The only way is to catch the Selecting event and prevent a tab from being activated.
The most tricky way is to make its parent equals null (make the tab alone without parent):
tabPage.Parent = null;
And when you want to return it back (will return it back at the end of pages collection) :
tabPage.Parent = tabControl;
And if you want to return it back in a specific location among the pages you can use :
tabControl.TabPages.Insert(indexLocationYouWant, tabPage);
I had to handle this a while back. I removed the Tab from the TabPages collection (I think that's it) and added it back in when the conditions changed. But that was only in Winforms where I could keep the tab around until I needed it again.
I've removed tab pages in the past to prevent the user from clicking them. This probably isn't the best solution though because they may need to see that the tab page exists.
Using events, and the properties of the tab control you can enable/disable what you want when you want. I used one bool that is available to all methods in the mdi child form class where the tabControl is being used.
Remember the selecting event fires every time any tab is clicked. For large numbers of tabs a "CASE" might be easier to use than a bunch of ifs.
public partial class Form2 : Form
{
bool formComplete = false;
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
formComplete = true;
tabControl1.SelectTab(1);
}
private void tabControl1_Selecting(object sender, TabControlCancelEventArgs e)
{
if (tabControl1.SelectedTab == tabControl1.TabPages[1])
{
tabControl1.Enabled = false;
if (formComplete)
{
MessageBox.Show("You will be taken to next tab");
tabControl1.SelectTab(1);
}
else
{
MessageBox.Show("Try completing form first");
tabControl1.SelectTab(0);
}
tabControl1.Enabled = true;
}
}
}
I've solved this problem like this:
I've got 3 tabs and I want to keep user at the first tab if he didnt log in,
so on the SelectingEvent of TabControl I wrote
if (condition) { TabControl.Deselect("2ndPage"); TabControl.Deselect("3dPage"); }
The user cannot click on tabs to navigate, but they can use the two buttons (Next and Back). The user cannot continue to the next if the //conditions are no met.
private int currentTab = 0;
private void frmOneTimeEntry_Load(object sender, EventArgs e)
{
tabMenu.Selecting += new TabControlCancelEventHandler(tabMenu_Selecting);
}
private void tabMenu_Selecting(object sender, TabControlCancelEventArgs e)
{
tabMenu.SelectTab(currentTab);
}
private void btnNextStep_Click(object sender, EventArgs e)
{
switch(tabMenu.SelectedIndex)
{
case 0:
//if conditions met GoTo
case 2:
//if conditions met GoTo
case n:
//if conditions met GoTo
{
CanLeaveTab:
currentTab++;
tabMenu.SelectTab(tabMenu.SelectedIndex + 1);
if (tabMenu.SelectedIndex == 3)
btnNextStep.Enabled = false;
if (btnBackStep.Enabled == false)
btnBackStep.Enabled = true;
CannotLeaveTab:
;
}
private void btnBackStep_Click(object sender, EventArgs e)
{
currentTab--;
tabMenu.SelectTab(tabMenu.SelectedIndex - 1);
if (tabMenu.SelectedIndex == 0)
btnBackStep.Enabled = false;
if (btnNextStep.Enabled == false)
btnNextStep.Enabled = true;
}
tabControl.TabPages.Remove(tabPage1);
This is an old question, but someone may benefit from my addition. I needed a TabControl that would show hidden tabs successively (after an action was performed on the current tab). So, I made a quick class to inherit from and called HideSuccessive() on Load:
public class RevealingTabControl : TabControl
{
private Action _showNextRequested = delegate { };
public void HideSuccessive()
{
var tabPages = this.TabPages.Cast<TabPage>().Skip(1);
var queue = new ConcurrentQueue<TabPage>(tabPages);
tabPages.ToList().ForEach(t => t.Parent = null);
_showNextRequested = () =>
{
if (queue.TryDequeue(out TabPage tabPage))
tabPage.Parent = this;
};
}
public void ShowNext() => _showNextRequested();
}
There is the XtraTabPage.PageEnabled property allowing you to disable certain pages.
Here the solution that i implement:
private void switchTapPage(TabPage tabPage)
{
foreach(TabPage page in tabControl1.TabPages)
{
tabControl1.TabPages.Remove(page);
}
tabControl1.TabPages.Add(tabPage);
}
Basically, i just call this method sending the tabPage that i currently need to show, the method will remove all the tabPages on the tabControl and after that it will just add the one that i sent it.
So the rest of the tabHeaders will not shown and they will be inaccessible, because they dont even exists in the tabControl.
I took the idea from the #stormenet answer.
You can do it through the tabpages: tabPage1.Hide(), tabPage2.Show() etc.
In the form load event if we write this.tabpage.PageEnabled = false, the tabpage will be disabled.
Assume that you have these controls:
TabControl with name tcExemple.
TabPages with names tpEx1 and tpEx2.
Try it:
Set DrawMode of your TabPage to OwnerDrawFixed;
After InitializeComponent(), make sure that tpEx2 is not enable by adding this code:
((Control)tcExemple.TabPages["tpEx2").Enabled = false;
Add to Selection tcExemple event the code below:
private void tcExemple_Selecting(object sender, TabControlCancelEventArgs e)
{
if (!((Control)e.TabPage).Enabled)
{
e.Cancel = true;
}
}
Attach to DrawItem event of tcExemple this code:
private void tcExemple_DrawItem(object sender, DrawItemEventArgs e)
{
TabPage page = tcExemple.TabPages[e.Index];
if (!((Control)page).Enabled)
{
using (SolidBrush brush = new SolidBrush(SystemColors.GrayText))
{
e.Graphics.DrawString(page.Text, page.Font, brush, e.Bounds);
}
}
else
{
using (SolidBrush brush = new SolidBrush(page.ForeColor))
{
e.Graphics.DrawString(page.Text, page.Font, brush, e.Bounds);
}
}
}
It will make the second tab non-clickable.
I could not find an appropriate answer to the question. There looks to be no solution to disable the specific tab. What I did is to pass the specific tab to a variable and in SelectedIndexChanged event put it back to SelectedIndex:
//variable for your specific tab
int _TAB = 0;
//here you specify your tab that you want to expose
_TAB = 1;
tabHolder.SelectedIndex = _TAB;
private void tabHolder_SelectedIndexChanged(object sender, EventArgs e)
{
if (_TAB != 0) tabHolder.SelectedIndex = _TAB;
}
So, you don't actually disable the tab, but when another tab is clicked it always returns you to the selected tab.
in C# 7.0, there is a new feature called Pattern Matching. You can disable all tabs via Type Pattern.
foreach (Control control in Controls)
{
// the is expression tests the variable and
// assigned it to a new appropriate variable type
if (control is TabControl tabs)
{
tabs.Enabled = false;
}
}
Use:
tabControl1.TabPages[1].Enabled = false;
By writing this code, the tab page won't be completely disabled (not being able to select), but its internal content will be disabled which I think satisfy your needs.
The solution is very simple.
Remove/comment this line
this.tabControl.Controls.Add(this.YourTabName);
in IntializeComponent() method in MainForm.cs
MyTabControl.SelectedTab.Enabled = false;

Categories

Resources