C# label should do diffrent things when clicked - c#

I need a label which does something different with every click.
private void open_Click(object sender, EventArgs e)
{
for (int i = 0; i < 5; i++)
{
builder = new StringBuilder(4);
builder.Append(zahl1.Text);
builder.Append(zahl2.Text);
builder.Append(zahl3.Text);
builder.Append(zahl4.Text);
code = builder.ToString();
}
if( code== setCode)
{
openAndClose.BackColor = Color.DarkGreen;
setNewCode.Visible = true;
}
else
{
}
}
With the first click the BackColor gets green and the visible is true.
And now it should go back in the start position if I click it again.
That means BackColor should be red and the visible should be false.
Can I do this wth a second Eventhandler?
openAndClose.Click += new EventHandler(open_Click);
Thanks

You could simply do the following:
if(code == setCode)
{
openAndClose.BackColor = openAndClose.BackColor == Color.DarkGreen ? Color.Red : Color.DarkGreen;
setNewCode.Visible = !setNewCode.Visible;
}
The first part toggles the color between green and red, and the second part toggles the visibility.

You should be able to get what you want by having a global field which denotes if the label has been clicked before hand or not.
In short, initially set your flag to false, do something like so:
EventHandler()
{
if(!flag)
{
BackColour = Green
Visible = true
}
else
{
BackColour = Red
Visible = false
}
flag = !flag
}
Attaching multiple event handlers will simply invoke multiple event handlers each time.

I think you do not even need a extra boolean or the check. You can just check if visible then hide, if not visible make it appear

Related

How can I uncheck radiobuttons in C# while still allowing only the first radiobutton to be tabbable?

Not sure if the title makes much sense, so here is the full context:
I'm coding in C#.
I've made an app with several UserControls, each one with many textboxes and radiobuttons.
All radiobuttons are placed in a panel in a set of 2, looking like this:
[ <label> O <radiobutton1text> O <radiobutton2text> ]
(while the first radiobutton have TabStop = true, and the second's TabStop = false)
When tabbing to such panel, only radiobutton1text is focused, and when hitting the LeftArrow key the radiobutton2text is selected. That's the desired outcome.
In order to make a UserControl load faster the second (and above) time, I'm not closing it but rather replacing it with a different UserControl each time the contents need to change.
But this rises an issue: When UserControl X is open, then on top of it I open UserControl Y and then back to X, the textboxes and radiobuttons still have the contents from the first session of when I had UserControl X open for the first time. (I need the contents of textboxes and radiobuttons to be reset after replacing a UserControl).
So I made a function that loops through all controls and empties their contents.
The problem is, when I uncheck the radiobuttons (and restore their TabStop state to true) in this function, the second radiobutton is tabbable after I check either one of them and then invoke the function, whereas it wasn't before going through this function.
The function:
public void BackToMain(object sender, EventArgs e)
{
// Go through all controls and empty each TextBox, RichTextBox, RadioButton or ComboBox.
int parentControlsCount = Controls.Count - 1;
for (int i = parentControlsCount; i >= 0; i--)
{
if (Controls[i].HasChildren == true)
{
int childrenControlsCount = Controls[i].Controls.Count - 1;
for (int j = childrenControlsCount; j >= 0; j--)
{
var controlType = Controls[i].Controls[j].GetType().ToString();
switch (controlType)
{
case "System.Windows.Forms.TextBox":
case "System.Windows.Forms.RichTextBox":
Controls[i].Controls[j].Text = null;
break;
case "System.Windows.Forms.RadioButton":
// Restore both properties to default value
((RadioButton)Controls[i].Controls[j]).Checked = false;
if (j == 1)
((RadioButton)Controls[i].Controls[j]).TabStop = true;
else if (j == 2)
((RadioButton)Controls[i].Controls[j]).TabStop = false;
break;
case "System.Windows.Forms.ComboBox":
((ComboBox)Controls[i].Controls[j]).SelectedIndex = -1;
break;
}
}
}
}
}
What am I doing wrong?
I ended up applying this gross hack- a function on every second radiobutton's CheckedChange:
private void DisableTabStopOnCheckedChange(object sender, EventArgs e)
{
// Assume the following STR:
// 1. In any radiobutton panel, select any radiobutton (without ever invoking BackToMain function in the first post);
// 2. Invoke the BackToMain function;
// 3. In the same radiobutton panel as in step #1, click the second radiobutton.
// Normally, without this function, if the user will now cycle through the controls using the Tab key, both the first and second radiobuttons will be tabbable,
// and that's because in the BackToMain function we reset their Checked and TabStop properies, and that's something that should be handled automatically by the control itself.
// Doing it manually means that for the *first time* selecting the second radiobutton, the first one's TabStop state won't update, which means both radiobuttons
// will have the TabStop state set to true, causing both to be tabbable.
// This is a gross hack to fix this by disabling TabStop on the first radio button if the second one is checked and the first one's TabStop state
// is true (this should happen only after BackToMain has been invoked).
if (((RadioButton)sender).Checked)
{
var firstRadioButton = ((RadioButton)sender).Parent.Controls[1];
if (((RadioButton)firstRadioButton).TabStop == true)
{
((RadioButton)firstRadioButton).TabStop = false;
}
}
}
Not a pretty solution, I know. But it works.

How to change opacity of certain number of button(x) while not writing them out one by one? (C#)

I don't think I asked the question quite well, so here's an explanation. I want to create buttons invisibly when Form1 loads, instead of changing them each individually, is there a way to change all of them with fewer lines of code?
Note: I do not want to change all buttons, only a certain range of them.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
button1.Visible = true;
button2.Visible = true;
button3.Visible = true;
button4.Visible = true;
button5.Visible = true;
button6.Visible = true;
button7.Visible = true;
}
By that I mean, is it possible to change those buttons visibility to true without writing them out one by one?
button1 - button7.Visible = true;
something like this..
If you're trying to change only a certain range of buttons, assuming they're all simply called button[x] you could create a function like this:
private void toggleButtons(int start, int end, bool trueOrFalse)
{
for(int x=start; x <= end; x++)
{
this.Controls.OfType<Button>().Where(b => b.Name == "button" + x.ToString()).SingleOrDefault().Visible = trueOrFalse;
}
}
Then you can call it like this using (startNo,endNo,true/false for visibility)
toggleButtons(1, 7, false);
You can use the Controls property to get all of the controls on a form. For example:
foreach(var button in this.Controls.OfType<Button>())
{
button.Visible = false;
}
If you want to change visibility of all buttons in the form, you could do so.
foreach(var button in Controls.OfType<Button>())
{
button.Visible = false; // or true, depending what you want to set
}
If you do no want to change visibility of all Buttons in Form and if you need to filter buttons, based on some criteria, you could do so as well.
For example, if you want to filter buttons whose names starts with "specialButton",
foreach(var button in this.Controls.OfType<Button>().Where(x=>x.Name.StartsWith("specialButton")))
{
button.Visible = false;
}
Similarly, you can filter based on other properties as well.
Another option is to enlist the buttons that needs to be changed in a list. For example, if you need to change only button1 and button2 from a form comprising of 10 buttons, you could
var list = new[] { button1, button2 };
foreach (var item in list)
{
item.Visible = false;
}

Expander menu in C #

I am trying to reproduce the operation of the Control Expander WPF, or as shown in the menu of Outlook, Vertical Web Menu etc., since in WindowsForms this control does not exist. Here I leave the sample code: Menu_Expader.zip link GoogleDrive.
I have managed to do it using the following controls:
Panels
FlowLayoutPanel
1 Time Control
Button Vectors
Labels Vectors ...
This works perfectly, but it happens that to each panel I must establish a
Maximum Size and Minimum Size therefore every time I add an item inside I must modify the size of the panel where I add it, and the item are very close to each other is a bit annoying for the user's vision.
Example this is what I currently have:
EDIT
Code Sample:
// The state of an expanding or collapsing panel.
private enum ExpandState
{
Expanded,
Expanding,
Collapsing,
Collapsed,
}
// The expanding panels' current states.
private ExpandState[] ExpandStates;
// The Panels to expand and collapse.
private Panel[] ExpandPanels;
// The expand/collapse buttons.
private Button[] ExpandButtons;
// Initialize.
private void Form1_Load(object sender, EventArgs e)
{
// Initialize the arrays.
ExpandStates = new ExpandState[]
{
ExpandState.Expanded,
ExpandState.Expanded,
ExpandState.Expanded,
};
ExpandPanels = new Panel[]
{
panModule1,
panModule2,
panModule3,
};
ExpandButtons = new Button[]
{
btnExpand1,
btnExpand2,
btnExpand3,
};
// Set expander button Tag properties to give indexes
// into these arrays and display expanded images.
for (int i = 0; i < ExpandButtons.Length; i++)
{
ExpandButtons[i].Tag = i;
ExpandButtons[i].Image = Properties.Resources.expander_down;
}
}
// Start expanding.
private void btnExpander_Click(object sender, EventArgs e)
{
// Get the button.
Button btn = sender as Button;
int index = (int)btn.Tag;
// Get this panel's current expand
// state and set its new state.
ExpandState old_state = ExpandStates[index];
if ((old_state == ExpandState.Collapsed) ||
(old_state == ExpandState.Collapsing))
{
// Was collapsed/collapsing. Start expanding.
ExpandStates[index] = ExpandState.Expanding;
ExpandButtons[index].Image = Properties.Resources.expander_up;
}
else
{
// Was expanded/expanding. Start collapsing.
ExpandStates[index] = ExpandState.Collapsing;
ExpandButtons[index].Image = Properties.Resources.expander_down;
}
// Make sure the timer is enabled.
tmrExpand.Enabled = true;
}
// The number of pixels expanded per timer Tick.
private const int ExpansionPerTick = 7;
// Expand or collapse any panels that need it.
private void tmrExpand_Tick(object sender, EventArgs e)
{
// Determines whether we need more adjustments.
bool not_done = false;
for (int i = 0; i < ExpandPanels.Length; i++)
{
// See if this panel needs adjustment.
if (ExpandStates[i] == ExpandState.Expanding)
{
// Expand.
Panel pan = ExpandPanels[i];
int new_height = pan.Height + ExpansionPerTick;
if (new_height >= pan.MaximumSize.Height)
{
// This one is done.
new_height = pan.MaximumSize.Height;
}
else
{
// This one is not done.
not_done = true;
}
// Set the new height.
pan.Height = new_height;
}
else if (ExpandStates[i] == ExpandState.Collapsing)
{
// Collapse.
Panel pan = ExpandPanels[i];
int new_height = pan.Height - ExpansionPerTick;
if (new_height <= pan.MinimumSize.Height)
{
// This one is done.
new_height = pan.MinimumSize.Height;
}
else
{
// This one is not done.
not_done = true;
}
// Set the new height.
pan.Height = new_height;
}
}
// If we are done, disable the timer.
tmrExpand.Enabled = not_done;
}
I want to get a result similar to this - Bootstrap Menu Accordion:
 
Imitate that operation panels expand according to the quantity of item that it contains as long as it does not protrude from the screen, in which case it will show the scroll bar. I know there are software that provide custom controls like DVexpress, DotNetBar Suite among others, but they are Licensed Software I do not want to use it illegally pirate. Can you help me optimize it or create it in another way?
Environment: Visual Studio 2010 & .NET NetFramework 4.
The original question I made it in StackOverFlow in Spanish.
Modulo (Module)
Menu Principal (Main menu)
Mantenimientos (Maintenance)
Procesos (Processes)
Consultas (Queries)
Reportes (Reports)
Note: If someone speaks Spanish and English and can do a better translation, please edit the question. (Excuse the advertising on the image, I recorded the screen with a software trial version).

Centering text on a button in a WinForms application

I have a simple Windows Forms application with a tabControl. I have 3 panels on the tabControl, each having 5 buttons. The text on first set of buttons is hard-coded, but the next set populates when you click one from the first group, and then the same thing happens again for the last group when you click one of the buttons from the second group. In the [Design] view I manually set the TextAlign property of each button to MiddleCenter. However, when I run the application the text on the middle set of buttons is never centered. It is always TopLeft aligned. I've tried changing the font size and even explicitly setting the TextAlign property every time I set button text programmatically, as follows:
private void setButtons(List<string> labels, Button[] buttons)
{
for (int i = 0; i < buttons.Count(); i++)
{
if (i < labels.Count)
{
buttons[i].Text = labels.ElementAt(i);
buttons[i].TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
buttons[i].Enabled = true;
}
else
{
buttons[i].Text = "";
buttons[i].Enabled = false;
}
}
}
This image shows the result:
Does anyone have any ideas for what I'm missing?
Trim text which you are assign to button. Also you can refer label by index, without calling ElementAt
private void setButtons(List<string> labels, Button[] buttons)
{
for (int i = 0; i < buttons.Count(); i++)
{
Button button = buttons[i];
if (i < labels.Count)
{
button.Text = labels[i].Trim(); // trim text here
// button.TextAlign = ContentAlignment.MiddleCenter;
button.Enabled = true;
}
else
{
button.Text = "";
button.Enabled = false;
}
}
}
You can set the UseCompatibleTextRendering property to true, then use the TextAlign property.
The strings in the SQL table that were assigned to the middle column were actually nchar(50), not nvarchar(50), which explains the problem. I added .Trim() to the Text assignment and it looks great now.
You can use the TextAlign from the Properties Menu and set it to MiddleCenter ...
If this does not work then the text you have for your button is larger than the actual button itself... to which you should either rescale your Font Size to a lower base size or a percent size of the actual button by using
btnFunction.Font = new Font(btnFunction.Font.Name, Convert.ToInt32(btnFunction.Height * 0.3333333333333333));
This would cause the button's font to be one third of the height of the button....

How to highlight node in TreeView ? Not only text area, but all row

TreeNode.Select() doesn't work. I want it to be highlighted like
All that I have is
You can use TreeView.FullRowSelect property for this. But remember, it is ignored if ShowLines is set to true.
TreeView.FullRowSelect Property
Gets or sets a value indicating whether the selection highlight spans the width of the tree view control.
public class CustomizedTreeView : TreeView
{
public CustomizedTreeView()
{`enter code here`
// Customize the TreeView control by setting various properties.
BackColor = System.Drawing.Color.CadetBlue;
FullRowSelect = true;
HotTracking = true;
Indent = 34;
ShowPlusMinus = false;
// The ShowLines property must be false for the FullRowSelect
// property to work.
ShowLines = false;
}
protected override void OnAfterSelect(TreeViewEventArgs e)
{
// Confirm that the user initiated the selection.
// This prevents the first node from expanding when it is
// automatically selected during the initialization of
// the TreeView control.
if (e.Action != TreeViewAction.Unknown)
{
if (e.Node.IsExpanded)
{
e.Node.Collapse();
}
else
{
e.Node.Expand();
}
}
// Remove the selection. This allows the same node to be
// clicked twice in succession to toggle the expansion state.
SelectedNode = null;
}
}
follow this link
https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.treeview.padding?view=netframework-4.7.2

Categories