In my WinForms Visual Studio application i have a checkbox styled as a Flat Button with this C# code:
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
if (TestBox.Checked == true)
{
TestBox.Image = Image.FromFile("M:\\CheckBox_52x.png");
TestBox.ImageAlign = ContentAlignment.MiddleCenter;
TestBox.FlatAppearance.BorderSize = 0;
// make all four (!) BackColors transparent!
TestBox.BackColor = System.Drawing.Color.Transparent;
TestBox.FlatAppearance.CheckedBackColor = Color.Transparent;
TestBox.FlatAppearance.MouseDownBackColor = Color.Transparent;
}
else
{
TestBox.Image = Image.FromFile("M:\\CheckBoxUncheck_52x.png");
TestBox.ImageAlign = ContentAlignment.MiddleCenter;
TestBox.FlatAppearance.BorderSize = 0;
// make all four (!) BackColors transparent!
TestBox.BackColor = System.Drawing.Color.Cyan;
TestBox.FlatAppearance.CheckedBackColor = Color.Cyan;
TestBox.FlatAppearance.MouseDownBackColor = Color.Cyan;
}
}
I was wondering, if instead of doing this to every single checkbox in my application, can i make the "UNCHECKED" version i have coded the default checkbox style for this applicatiom - eg - every time i create a new one it appears with these properties.
Please keep in mind that i am brand new to coding in C#.
If you want multiple controls to use the same eventhandler, that's easy - just use the same event handler. Change your code to something like:
private void HandleCheckBoxCheckedChanged(object sender, EventArgs e)
{
CheckBox checkBox = (CheckBox) sender;
string imageFile;
Color color;
if (checkBox.Checked == true)
{
// TODO: Use resources embedded within your app
imageFile = "M:\\CheckBox_52x.png";
color = Color.Transparent;
}
else
{
imageFile = "M:\\CheckBoxUncheck_52x.png";
color = Color.Cyan;
}
// TODO: Load each file once and reuse the bitmap, I suspect.
checkBox.Image = Image.FromFile(imageFile);
checkBox.ImageAlign = ContentAlignment.MiddleCenter;
checkBox.FlatAppearance.BorderSize = 0;
checkBox.BackColor = color;
checkBox.FlatAppearance.CheckedBackColor = color;
checkBox.FlatAppearance.MouseDownBackColor = color;
}
You can then attach the same handler to all your checkboxes.
If you have multiple classes, you could make that a public static method. At that point you may need to add the event handler in code rather than getting the designer to do it - I don't know whether the designer knows how to use static methods for event handlers. But it would just be something like:
TestBox.CheckedChanged += CheckBoxUtilities.HandleCheckBoxCheckedChanged;
That's if you really just want the same code to be used for event handlers. Other things to consider are:
Constructing a subclass of CheckBox as suggested by rakatherock. My own experience with creating custom controls in Windows Forms has not been great, but from an OO perspective it feels fine. An initial implementation could just derive from CheckBox and implicitly add an event handler which does exactly what your current code does.
If you want to find all the CheckBox controls in a form at some point, you can use the Controls property and then recurse through any control which itself a container. I won't go into the details of that now though, as it sounds like you don't really want this - unless you did it just to find all the CheckBox controls and add the same event handler to all of them.
This can be done by creating custom checkbox control.
From the question what you are trying to do is to manipulate all check boxes in the application from a single check box so here the logic goes like:
Save the All checkbox value(Checked or unchecked) in the settings
To create a settings value
Right Click Project>Properties>Settings>Give Name as someBoolValue,type as bool,Scope as User
So on CheckChanged event of this check box save the value in Settings variable that we have created just now.In CheckChangedEvent of main All Check box code goes like:
Properties.Settings.Default.someBoolValue=cbCheckBox.Checked;
Properties.Settings.Default.Save();
Now on every form load are where ever the event is suitable do like
foreach(Control c in this.Controls)
{
if(c is CheckBox)
{
c.Checked=Properties.Settings.Default.someBoolValue
}
}
Note:You can replace all the check box that i implemented with your custom controls.I have given you just an idea how to do it.
Related
Hey so I am attempting to create a form in which there are two buttons (acting as tabs) on the side in which when one is pressed specific controls are shown and when the other is pressed, another set are shown.
I have gotten this to work very well however I have run into an issue when about to create my second set of controls, how am I going to draw them (in designer) ontop of current controls (it's fine during runtime)? So my question is, how can I make this work. Current (possibly) important code:
private void CheatButton_Click(object sender, EventArgs e)
{
CheatControls(true);
ColorControls(false);
CheatButton.Normalcolor = Color.FromArgb(51, 51, 51);
ColorButton.Normalcolor = Color.FromArgb(61, 61, 61);
}
private void ColorButton_Click(object sender, EventArgs e)
{
CheatControls(false);
ColorControls(true);
CheatButton.Normalcolor = Color.FromArgb(61, 61, 61);
ColorButton.Normalcolor = Color.FromArgb(51, 51, 51);
}
private void CheatControls(bool b)
{
TriggerSwitch.Visible = b;
TriggerLabel.Visible = b;
BhopSwitch.Visible = b;
BhopLabel.Visible = b;
GlowSwitch.Visible = b;
GlowLabel.Visible = b;
RecoilSwitch.Visible = b;
RecoilLabel.Visible = b;
}
private void ColorControls(bool c)
{
}
My windows form application with an understandable graphic
Put all your cheat controls in a custom UserControl and all your color controls in a different custom UserControl. You can edit the different control sets easily in the designer, and in your code you can hide/show them more easily by setting the appropriate UserControl's visibility rather than setting the visibility of a bunch of controls individually. Here's an (admittedly old) example of creating a UserControl: msdn.microsoft.com/en-us/library/aa302342.aspx
When you create a UserControl in Visual Studio, you can add the controls to it using the designer. In your form with the tab buttons, you would add instances of the two UserControls that you created. Since UserControl derives from Control, it has a Visible property. So, in your CheatControls(bool b) method, your implementation would be simplified to something like _myCheatControls.Visible = b;. I haven't watched the whole thing, but this video might help, too: youtube.com/watch?v=l5L_q_jI494
You can use
XanderUI
Simply add a SuperButton(acts as a tab button) and when its clicked show a panel with your controls in it
EG -
private void ShowControlSet(int ControlSet)
{
panel1.visible = false;
panel2.visible = false;
if (ControlSet == 1) panel1.visible = true;
if (ControlSet == 2) panel2.visible = true;
}
// To show a panel use
ShowControlSet(1);
Your also able to use BringToFront() instead of making each panel invisible / visible but you need to anchor or dock the panels correctly
asides the visibility, what you can do is get the position of the buttons and st them when hiding and showing the other buttons
just set the top and left positions, ensuring the buttons are the same size.
I'm a newbie in c# and probably going to ask a very easy question, but I've not been able to find anything on the web to help.
I have a tabControl with a TabPage which is containing a TextBox object; this object, when the event "Text changed" is invoked, will perform the change of the parent tabPage's name.
The textbox where I typed "text changed by me" has a method which is managing changing the name of the tabPage:
private void textBox1_TextChanged(object sender, EventArgs e)
{
if (this.textBox1.Text != "")
this.tabControl2.SelectedTab.Text = this.textBox1.Text;
else
this.tabControl2.SelectedTab.Text = "(no name)";
}
Into the current page menu is contained a control to add a new page, which runs this method when the user click on it:
private void addNewPageToolStripMenuItem_Click(object sender, EventArgs e)
{
int numPagine;
string strPagine;
numPagine = this.tabControl2.TabCount;
strPagine = numPagine.ToString();
this.tabControl2.TabPages.Add("new page" + strPagine);
}
...and here is the output, which is expected since I'm just asking to add a new empty tabPage:
So, my question is: how can I make possible that when the user is clicking on "Add new page", rather than creating an empty new tabPage the program is rather creating a page like the first one (i.e. containing a textbox into the same position which has a method to change the text of the parent tabPage that I have just created?
Here is an example.
//..
// create the new page
TabPage tpNew = new TabPage("new page..");
// add it to the tab
this.tabControl2.TabPages.Add(tpNew);
// create one labe with text and location like label1
Label lbl = new Label();
lbl.Text = label1.Text;
lbl.Location = label1.Location;
// create a new textbox..
TextBox tbx = new TextBox();
tbx.Location = textBox1.Location;
tpNew.Controls.Add(lbl);
tpNew.Controls.Add(tbx);
// add code to the new textbox via lambda code:
tbx.TextChanged += ( (sender2, evArgs) =>
{
if (tbx.Text != "")
this.tabControl2.SelectedTab.Text = tbx.Text;
else
this.tabControl2.SelectedTab.Text = "(no name)";
} );
For more complicated layout you may want to consider creating a user control..
You also may want to create the first page with this code; the, of course with real values for text and positions!
For creating a UserControl you go to the project tag and right click Add-UserControl-UserControl and name it, maybe myTagPageUC. Then you can do layout on it like on a form. A rather good example is right here on MSDN
The problem is that is has no connection to the form, meaning you'll have to code all sorts of references to make it work..
I'm not really sure if you may not be better off writing a complete clonePage method instead. It could work like the code above, but would loop over the Controls of the template page and check on the various types to add the right controls..
It really depends on what is more complicated: the Layout or the ties between the pages and the form and its other controls..
Sorry for the poor quality of the title. I couldn't think of a better way to phrase this.
For a project I'm currently working on with a few friends, I got myself in the situation where I have created a dynamic form (with reflection) which I now want to validate.
Example (ignore the black box, it contains old form elements which are now irrelevant and i didn't want to confuse you guys):
As you may have guessed already, it is an application for creating a mysql database.
Which is where I get to my problem(s). I want to disable checkboxes if others are checked.
For example: If I check "PrimaryKey" I want to disable the checkbox "Null".
Changing from unsigned to signed changes the numericupdown minimum and maximum etc.
But with reflection and all, I find it difficult to know exactly which checkbox to disable.
I was hoping you guys would have some suggestions.
I have been thinking about this for a while and a few thoughts have come to mind. Maybe these are better solutions than the current one.
Thought 1: I create UserControls for every datatype. Pro's: no problems with reflection and easy identifying of every control in the UserControl for validation. Con's: Copy-Pasting, Lots of UserControls, with a lot of the same controls.
Thought 2: Doing something with the description tags for every property of the classes. Creating rules in the description that allow me to link the checkboxes together. Here I'll only have to copy the rules to every class property and then it should be ok.
I had been thinking of other solutions but I failed to remember them.
I hope you guys can give me a few good pointers/suggestions.
[Edit]
Maybe my code can explain a bit more.
My code:
PropertyInfo[] properties = DataTypes.DataTypes.GetTypeFromString(modelElement.DataType.ToString()).GetType().GetProperties();
foreach (PropertyInfo prop in properties)
{
if (prop.Name != "Label" && prop.Name != "Project" && prop.Name != "Panel")
{
var value = prop.GetValue(modelElement.DataType, null);
if (value != null)
{
tableLayoutPanel1.Controls.Add(new Label { Text = prop.Name, Anchor = AnchorStyles.Left, AutoSize = true });
switch (value.GetType().ToString())
{
case "System.Int32":
NumericUpDown numericUpDown = new NumericUpDown();
numericUpDown.Text = value.ToString();
numericUpDown.Dock = DockStyle.None;
tableLayoutPanel1.Controls.Add(numericUpDown);
break;
case "System.Boolean":
CheckBox checkBox = new CheckBox();
checkBox.Dock = DockStyle.None;
// checkbox will become huge if not for these changes
checkBox.AutoSize = false;
checkBox.Size = new Size(16, 16);
if (value.Equals(true))
{
checkBox.CheckState = CheckState.Checked;
}
tableLayoutPanel1.Controls.Add(checkBox);
break;
default:
MessageBox.Show(#"The following type has not been implemented yet: " + value.GetType());
break;
}
}
}
}
Here is a mockup from my comments:
// The ViewModel is responsible for handling the actual visual layout of the form.
public class ViewModel {
// Fire this when your ViewModel changes
public event EventHandler WindowUpdated;
public Boolean IsIsNullCheckBoxVisible { get; private set; }
// This method would contain the actual logic for handling window changes.
public void CalculateFormLayout() {
Boolean someLogic = true;
// If the logic is true, set the isNullCheckbox to true
if (someLogic) {
IsIsNullCheckBoxVisible = true;
}
// Inform the UI to update
UpdateVisual();
}
// This fires the 'WindowUpdated' event.
public void UpdateVisual() {
if (WindowUpdated != null) {
WindowUpdated(this, new EventArgs());
}
}
}
public class TheUI : Form {
// Attach to the viewModel;
ViewModel myViewModel = new ViewModel();
CheckBox isNullCheckBox = new CheckBox();
public TheUI() {
this.myViewModel.WindowUpdated += myViewModel_WindowUpdated;
}
void myViewModel_WindowUpdated(object sender, EventArgs e) {
// Update the view here.
// Notie that all we do in the UI is to update the visual based on the
// results from the ViewModel;
this.isNullCheckBox.Visible = myViewModel.IsIsNullCheckBoxVisible;
}
}
The basic idea here is that you ensure that the UI does as little as possible. It's role should just be to update. Update what? That's for the ViewModel class to decide. We perform all of the updating logic in the ViewModel class, and then when the updating computations are done, we call the UpdateVisual() event, which tells the UI that it needs to represent itself. When the WindowUpdated Event occurs, the UI just responds by displaying the configuration set up by the ViewModel.
This may seem like a lot of work to set up initially, but once in place it will save you tons and tons of time down the road. Let me know if you have any questions.
Try relating the event of one checkbox to disable the other; something like this:
private void primaryKeyBox_AfterCheck(object sender, EventArgs e)
{
nullBox.Enabled = false;
}
This is a very simple example and would have to be changed a bit, but for what I think you're asking it should work. You would also have to add to an event for the boxes being unchecked. You would also need logic to only get data from certain checkboxes based on the ones that are and are not checked.
For all the other things, such as changing the numbers based on the dropdown, change them based on events as well.
For WinForms I would use data binding.
Create an object and implement INotifyPropertyChanged and work with that object.
Then, If you have an object instance aObj:
To bind the last name property to a textbox on the form do this:
Private WithEvents txtLastNameBinding As Binding
txtLastNameBinding = New Binding("Text", aObj, "LastName", True, DataSourceUpdateMode.OnValidation, "")
txtLastName.DataBindings.Add(txtLastNameBinding)
Take a look here for more info.
INotifyPropertyChanged
I have some DomainUpDown controls in my winforms application. I cant find an option to set the default value for them on start up. Is there a way to do this?
At the moment, I have an enum type like this:
public enum ComparisonMode {Settings, Readings};
And I have set the SelectedItemChanged event of each DomainUpDown control to something like this:
private ComparisonMode ComparisonA; //enum to hold state of upDownA
private void upDownA_SelectedItemChanged(object sender, EventArgs e)
{
switch (upDownA.Text)
{
case "Settings":
ComparisonA = ComparisonMode.Settings;
break;
case "Readings":
ComparisonA = ComparisonMode.Readings;
break;
}
}
When I start the application, all the domainupdown controls have nothing selected, so user must set each of them to either Settings or Readings befor starting to work with the application.
How can I set for all of them a default value of for example (Readings)? I am thinking of looping over the controls (As they are inside a TableLayoutPanel).
I came up with this idea so far, It seems to work:
foreach (TableLayoutPanel tlp in tableCriterias.Controls)
{
foreach (Control ctrl in tlp.Controls)
{
var dud = ctrl as DomainUpDown;
if (dud != null)
{
dud.DownButton(); dud.DownButton();
//Going down 2 times to select default value
}
}
}
I do the above loop in the Load event of my form, but it makes everything very slow in the beggining since I have like 100 of these UpDown Controls.
No need to do this, you can set the SelectedIndex like this :
DomainUpDown dd = new DomainUpDown();
dd.Items.Add("settings");
dd.Items.Add("Reading");
dd.SelectedIndex = 0; // this will make sure you get the first item selected
I have some items in a CheckedListBox, I want to disable the CheckBox of first item in it.
i.e. I want to disable the first item in the CheckedListBox, because I want to tell the user visually that option is not available.
Combining 2 of the above partial answers worked great for me.
Add your items to the list with:
myCheckedListBox.Items.Add(myItem, myState);
Where myState is CheckState.Indeterminate for items that should be disabled.
Then add an event handler to keep those items from being changed:
myCheckedListBox.ItemCheck += (s, e) => { if (e.CurrentValue == CheckState.Indeterminate) e.NewValue = CheckState.Indeterminate; };
This does not allow you to use 'Indeterminate' in this list for its normal purpose but it does give a look very similar to what one would expect for a disabled item and it provides the correct behavior!
Though this post is pretty old, the last added answer has been submitted in April this year,
and I hope this will help someone.
I was after something similar : a checked list box that behaves like
a lot of installers, which offer a list of options where some features are required and
thus are both checked and disabled.
Thanks to this post (Can I use a DrawItem event handler with a CheckedListBox?)
I managed to do that, subclassing a CheckedListBox control.
As the OP in the linked post states, in the CheckedListBox control the OnDrawItem event is never fired,
so subclassing is necessary.
It's very basic, but it works.
This is what it looks like (the CheckBox above is for comparison) :
NOTE: the disabled item is really disabled : clicking on it has no effects whatsoever (as far as I can tell).
And this is the code :
public class CheckedListBoxDisabledItems : CheckedListBox {
private List<string> _checkedAndDisabledItems = new List<string>();
private List<int> _checkedAndDisabledIndexes = new List<int>();
public void CheckAndDisable(string item) {
_checkedAndDisabledItems.Add(item);
this.Refresh();
}
public void CheckAndDisable(int index) {
_checkedAndDisabledIndexes.Add(index);
this.Refresh();
}
protected override void OnDrawItem(DrawItemEventArgs e) {
string s = Items[e.Index].ToString();
if (_checkedAndDisabledItems.Contains(s) || _checkedAndDisabledIndexes.Contains(e.Index)) {
System.Windows.Forms.VisualStyles.CheckBoxState state = System.Windows.Forms.VisualStyles.CheckBoxState.CheckedDisabled;
Size glyphSize = CheckBoxRenderer.GetGlyphSize(e.Graphics, state);
CheckBoxRenderer.DrawCheckBox(
e.Graphics,
new Point(e.Bounds.X + 1, e.Bounds.Y + 1), // add one pixel to align the check gliph properly
new Rectangle(
new Point(e.Bounds.X + glyphSize.Width + 3, e.Bounds.Y), // add three pixels to align text properly
new Size(e.Bounds.Width - glyphSize.Width, e.Bounds.Height)),
s,
this.Font,
TextFormatFlags.Left, // text is centered by default
false,
state);
}
else {
base.OnDrawItem(e);
}
}
public void ClearDisabledItems() {
_checkedAndDisabledIndexes.Clear();
_checkedAndDisabledItems.Clear();
this.Refresh();
}
}
Use it like this:
checkedListBox.Items.Add("Larry");
checkedListBox.Items.Add("Curly");
checkedListBox.Items.Add("Moe");
// these lines are equivalent
checkedListBox.CheckAndDisable("Larry");
checkedListBox.CheckAndDisable(0);
Hope this can help someone.
Disabling items isn't a great idea, the user will have no good feedback that click the check box won't have any effect. You cannot use custom drawing to make it obvious. Best thing to do is to simply omit the item.
You can however easily defeat the user with the ItemCheck event:
private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e) {
if (e.Index == 0) e.NewValue = e.CurrentValue;
}
To disable any particular item use following:
checkedListBox1.SetItemCheckState(0, CheckState.Indeterminate);
SetItemCheckState takes index of item and CheckState Enum
Indeterminate is used to show shaded appearance
I know it has been a while, but I found this in my search for a list box and thought I would add it to the discussion.
If you have a listbox and want to disable all of the checkboxes so they cannot be clicked, but not disable the control so the user can still scroll etc. you can do this:
listbox.SelectionMode = SelectionMode.None
The CheckedListBox will not work in this way. CheckedListBox.Items is a collection of strings so they cannot be "disabled" as such.
Here are some discussions about possible solutions that might help you: here and here.
This works for me:
checkedListBox1.SelectionMode = SelectionMode.None;
Which means no items can be selected
None: No items can be selected.
For more info, you can check it here: SelectionMode Enumeration.
The solution is to use the event ItemChecking:
_myCheckedListBox.ItemChecking += (s, e) => e.Cancel = true;
This will cancel all the checking on every item, but you can always do more refined solution but testing the current .SelectedItem
Here's how I did it in a helpdesk application I wrote:
First, I made it so the check box was greyed out as I added it to the list during form load:
private void frmMain_Load(object sender, EventArgs e)
{
List<string> grpList = new List<string>();
ADSI objADSI = new ADSI();
grpList = objADSI.fetchGroups();
foreach (string group in grpList)
{
if (group == "SpecificGroupName")
{
chkLst.Items.Add(group, CheckState.Indeterminate);
}
else
{
chkLst.Items.Add(group);
}
}
Then I used an event so that when clicked it ensures it stays clicked:
private void chkLst_SelectedIndexChanged(object sender, EventArgs e)
{
if (chkLst.SelectedItem.ToString() == "SpecificGroupName")
{
chkLst.SetItemCheckState(chkLst.SelectedIndex, CheckState.Indeterminate);
}
}
The idea here is that on my form it's set so that the box checks on item click/select. This way I could kill two birds with one stone. I could keep this event from causing problems when the item is first checked and added during form load. Plus making it check on select allows me to use this event instead of the item checked event. Ultimately the idea is to keep it from messing up during the load.
You'll also notice that it doesn't matter what the index number is, that variable is unknown because in my app it's grabbing a list of groups from AD that exist in a specific OU.
As to whether this is a good idea or not, that's dependent on the situation. I have another app where the item to disable is dependent on another setting. In this app I just want the helpdesk to see that this group is required so they don't go removing them from it.
Try Below Code:
Private Sub CheckedListBox1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles CheckedListBox1.MouseUp
If (Condition) Then
Me.CheckedListBox1.SelectedIndex = -1
End If
End Sub
I think an alternative solution, is using Telerik components.
A RadListControl can give you that option: