I have a form with a ComboBox, which is populated with 3 items.
When I add the statements: comboBox1.Text = "A"; and comboBox1.DroppedDown = true;
the first item of the drop-down list is automatically selected: the comboBox1.Text shows "Abc" in stead of "A".
Here is the code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace testComboBox
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
comboBox1 = new ComboBox();
PopulateComboBox();
comboBox1.Location = new Point((this.Width - comboBox1.Width) / 2, 80);
this.Controls.Add(comboBox1);
comboBox1.Text = "A";
comboBox1.DroppedDown = true;
}
ComboBox comboBox1;
private void PopulateComboBox()
{
comboBox1.Items.Add("Abc");
comboBox1.Items.Add("Abcd");
comboBox1.Items.Add("Abcde");
}
private void button_Exit_Click(object sender, EventArgs e)
{
this.Close();
}
}
}
How can I disable the automatic selection of the first item in the Items collection of the ComboBox, so that the comboBox1.Text will show "A" and not "Abc"?
I am not looking for a one-time work-around. I need a GENERAL SOLUTION.
set this code comboBox1.SelectedText = null;
public Form1()
{
InitializeComponent();
comboBox1 = new ComboBox();
PopulateComboBox();
comboBox1.Location = new Point((this.Width - comboBox1.Width) / 2, 80);
this.Controls.Add(comboBox1);
comboBox1.SelectedText = "A";
comboBox1.DroppedDown = true;
comboBox1.SelectedText = null;
}
With the help of the thread that Loathing pointed to, I copied the extension Class ComboBoxAutoSelectExtension and in the form I just added the line of code: ComboBoxAutoSelectExtension.AutoSelectOff(comboBox1);
If you copy the ComboBoxAutoSelectEx from the link in the comment, then the only thing you should have to do in your own Form1 code is:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
comboBox1 = new ComboBox();
String text = "A";
comboBox1.Text = text;
comboBox1.Select(text.Length,1); // put cursor at the end of text
ComboBoxAutoSelectEx.AutoSelectOff(comboBox1); // Added
PopulateComboBox();
comboBox1.Location = new Point((this.Width - comboBox1.Width) / 2, 80);
this.Controls.Add(comboBox1);
}
protected override void OnLoad(EventArgs e) { // Added
base.OnLoad(e);
comboBox1.DroppedDown = true;
}
ComboBox comboBox1;
private void PopulateComboBox()
{
comboBox1.Items.Add("Abc");
comboBox1.Items.Add("Abcd");
comboBox1.Items.Add("Abcde");
}
private void button_Exit_Click(object sender, EventArgs e)
{
this.Close();
}
}
I see no way to disable auto selection of an item. I can only replace the wrong selection with the input text that was previously known. This bug occurs on both opening or closing the dropdown. Here is an example code when opening the dropdown.
// record
box_txt = comboBox1.Text;
box_pos = comboBox1.SelectionStart;
// drop down
comboBox1.DroppedDown = true;
// replace
comboBox1.Text = box_txt;
comboBox1.SelectionStart = box_pos;
Related
why can't I add a new item/object to my list in button (or combobox etc.) events? I mean, the events don't see my list if it's outside of the brackets...it's underlined in red... can you help me?
long story short: i want to add a new object by clicking the button
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Serialization;
using System.IO;
namespace Samochody
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
List<Samochod> ListaSamochodow = new List<Samochod>();
comboBox1.DataSource = ListaSamochodow;
comboBox1.DisplayMember = "Marka";
XmlRootAttribute oRootAttr = new XmlRootAttribute();
XmlSerializer oSerializer = new XmlSerializer(typeof(List<Samochod>), oRootAttr);
StreamWriter oStreamWriter = null;
oStreamWriter = new StreamWriter("samochody.xml");
oSerializer.Serialize(oStreamWriter, ListaSamochodow);
}
private void button1_Click(object sender, EventArgs e)
{
try
{
ListaSamochodow.Add(new Samochod(textBox1.Text, textBox2.Text, Convert.ToInt32(textBox3.Text)));
}
catch (Exception oException)
{
Console.WriteLine("Aplikacja wygenerowała następujący wyjątek: " + oException.Message);
}
}
I think you should instantiate your list globally and not under Form1_Load event.
that way it will be accessible all around your class (the window in this case).
This seems to work fine. You might need to set your textboxes to contain valid values when you start the form. also make sure that you make the list visible throughout your form1 class.
namespace Samochody
{
public partial class Form1 : Form
{
// make sure your list looks like this, created outside your functions.
List<Samochod> ListaSamochodow = new List<Samochod>();
public Form1()
{
InitializeComponent();
label1.Text = "the amount in your list is " + ListaSamochodow.Count.ToString();
textBox1.Text = "string here";
textBox2.Text = "string here";
textBox3.Text = "100";
}
private void Form1_Load(object sender, EventArgs e)
{
XmlRootAttribute oRootAttr = new XmlRootAttribute();
XmlSerializer oSerializer = new XmlSerializer(typeof(List<Samochod>), oRootAttr);
StreamWriter oStreamWriter = null;
oStreamWriter = new StreamWriter("samochody.xml");
oSerializer.Serialize(oStreamWriter, ListaSamochodow);
}
private void button1_Click_1(object sender, EventArgs e)
{
Samochod s = new Samochod(textBox1.Text, textBox2.Text, Convert.ToInt32(textBox3.Text));
ListaSamochodow.Add(s);
label1.Text = "the amount in your list is " + ListaSamochodow.Count.ToString();
}
}
}
Read them back in app constructor and also maybe in other places in program.
I have a new form i created with some checkboxes:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace Options
{
public partial class OptionsMenuForm : Form
{
public OptionsMenuForm()
{
InitializeComponent();
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
if (checkBox1.Checked)
{
Settings.downloadonstart = true;
}
else
{
Settings.downloadonstart = false;
}
}
private void checkBox2_CheckedChanged(object sender, EventArgs e)
{
if (checkBox2.Checked)
{
Settings.loadonstart = true;
}
else
{
Settings.loadonstart = false;
}
}
private void checkBox3_CheckedChanged(object sender, EventArgs e)
{
if (checkBox3.Checked)
{
Settings.startminimized = true;
}
else
{
Settings.startminimized = false;
}
}
private void checkBox4_CheckedChanged(object sender, EventArgs e)
{
if (checkBox4.Checked)
{
Settings.displaynotifications = true;
}
else
{
Settings.displaynotifications = false;
}
}
}
}
Now i want to save each time the state of one/any of the checkboxes.
I also added a class i'm using th pass the variables between the new form and form1:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Options
{
class Settings
{
public static bool downloadonstart;
public static bool loadonstart;
public static bool startminimized;
public static bool displaynotifications;
}
}
Now how can i use this in form1 by saving the settings to a text file ?
For example in the text file the content will be something like:
CheckBox1 = true
CheckBox2 = false
CheckBox3 = false
CheckBox4 = true
And then if i change the state of one of them it will write it in the text file:
CheckBox1 = false
CheckBox2 = false
CheckBox3 = true
CheckBox4 = true
In form1 top i added
string settingsFile = "settings.txt";
string settingsFileDirectory = "\\settings";
StreamWriter writetosettingsfile;
Then in constructor
settingsFileDirectory = Path.GetDirectoryName(Application.LocalUserAppDataPath) +
settingsFileDirectory;
if (!Directory.Exists(settingsFileDirectory))
{
Directory.CreateDirectory(settingsFileDirectory);
}
I know the app it self have a settings in the properties but i wanted to use a text file this time since i have many settings and i might have more later.
Or using the settings in the app in properties i did:
But now how do i use with it in my program to save every checkbox state in the new form and then using it in form1 ?
You can use json.net
Something like this to save the data
private void Form1_Load(object sender, EventArgs e)
{
checkBox1.CheckedChanged += checkBox_CheckedChanged;
checkBox2.CheckedChanged += checkBox_CheckedChanged;
checkBox3.CheckedChanged += checkBox_CheckedChanged;
checkBox4.CheckedChanged += checkBox_CheckedChanged;
}
private void checkBox_CheckedChanged(object sender, EventArgs e)
{
var settings = new Settings();
settings.downloadonstart = checkBox1.Checked;
settings.loadonstart = checkBox2.Checked;
settings.startminimized = checkBox3.Checked;
settings.displaynotifications = checkBox4.Checked;
File.WriteAllText(#"c:\configfile.json", JsonConvert.SerializeObject(settings));
}
You can read the file like this
Settings settings = JsonConvert.DeserializeObject<Settings>(File.ReadAllText(#"c:\configfile.json"));
Documentation:
http://www.newtonsoft.com/json/help/html/Introduction.htm
public OptionsMenuForm()
{
InitializeComponent();
//Read the settings from a file with comma delimited 1's and 0's or whatever you like
string[] values = System.IO.File.ReadAllText("c:\temp\a.txt").Split(',');
checkBox1.Checked = Convert.ToBoolean(Convert.ToInt32(values[0]));
checkBox2.Checked = Convert.ToBoolean(Convert.ToInt32(values[1]));;
//On checkbox changes save the settings
checkBox1.CheckedChanged +=SaveSettings;
checkBox2.CheckedChanged +=SaveSettings;
}
public void SaveSettings(object sender,EventArgs e)
{
StringBuilder sbValues = new StringBuilder();
int i = 0;
i = checkBox1.Checked ? 1 : 0;
sbValues.Append(i.ToString() + ",");
i = checkBox2.Checked ? 1 : 0;
sbValues.Append(i.ToString() + ",");
System.IO.File.WriteAllText("c:\temp\a.txt",sbValues.ToString());
}
It is recommended that you use XML when using the .NET framework.
public static void ConvertStringToXmlList()
{
XElement xml = new XElement
(
"Items",
(
from x in [YourList] select new XElement("Item", x)
)
);
XDocument doc = new XDocument
(
xml
);
doc.Save(Environment.CurrentDirectory + "/settings.xml");
}
var xmlReader = new XmlTextReader("settings.xml");
while (xmlReader.Read())
{
switch (reader.NodeType)
{
case [nodetype]:
// Code here
break;
}
}
Also, instead of creating the same event for all four checkbox's, just use 1.
Inside of the single event put:
ckCheckBox1.Checked = !ckCheckBox1.Checked;
I'm a complete noob in C# programming. This is my problem: I have a form with a panel that is generated upon clicking button 1, the panel also containes a button (btnColor1) to change the backcolor of the panel. I would like to refer to the panel's backcolor in btnColor1, but I get the error "The name 'btnColor1' does not exist in the current context". How can I fix this?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace TEST_APP_1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Panel myPanel1 = new Panel();
myPanel1.Location = new System.Drawing.Point(100, 50);
myPanel1.Name = "Panel 1";
myPanel1.Size = new System.Drawing.Size(200, 100);
myPanel1.BackColor = Color.Red;
TextBox textBox1 = new TextBox();
textBox1.Location = new Point(10, 50);
textBox1.Text = "empty field";
textBox1.Size = new Size(150, 30);
Button btnColor1 = new Button();
btnColor1.Location = new Point(10, 10);
btnColor1.Text = "GOLD";
btnColor1.Size = new Size(100, 30);
btnColor1.Click += myButton1_Click;
myPanel1.Controls.Add(textBox1);
myPanel1.Controls.Add(btnColor1);
Controls.Add(myPanel1);
}
private void myButton1_Click(object sender, EventArgs e)
{
throw new NotImplementedException();
btnColor1.BackColor = Color.Gold;
}
}
}
btnColor1 is declared in the scope of the button1_Click method so does not exist as a variable to reference in your event handler. Change the event handler to this:
private void myButton1_Click(object sender, EventArgs e)
{
throw new NotImplementedException();
(sender as Button).BackColor = Color.Gold;
}
You can try to use the parent property of the button to access the panel and the form:
private void myButton1_Click(object sender, EventArgs e)
{
Button but = (sender as Button);
but.BackColor = Color.Gold;
// this changes the color of the panel
but.Parent.BackColor = Color.Gold;
// this changes the color of the form containing the panel
if (but.Parent.Parent != null)
{
but.Parent.Parent.BackColor = Color.Gold;
}
}
I am trying to make a button that when clicked pops up a new form with a yes and no button and then make an if statement based on what button is pressed. Here is my current code:
private YesNoMessageBoxResized newBoxResized;
private string buttonClickResult;
public void YesNoNewMessageBox(string title, string message,string buttonYes, string buttonNo)
{
YesNoMessageBoxResized msgResized = new YesNoMessageBoxResized(title, message, buttonYes, buttonNo);
msgResized.StartPosition = FormStartPosition.CenterScreen;
msgResized.TopMost = true;
Button yesButtonResize = new Button();
Button noButtonResize = new Button();
//yes button
yesButtonResize.Text = buttonYes;
yesButtonResize.Size = new Size(150, 80);
yesButtonResize.Font = new Font("Arial", 26);
yesButtonResize.Location = new Point(100, 150);
//no button
noButtonResize.Text = buttonNo;
noButtonResize.Size = new Size(150, 80);
noButtonResize.Font = new Font("Arial", 26);
noButtonResize.Location = new Point(300, 150);
//make a copy of the current form
newBoxResized = msgResized;
//eventhandlers
yesButtonResize.Click += YesButtonResizeClicked;
noButtonResize.Click += noButtonResizeClicked;
newBoxResized.Controls.Add(yesButtonResize);
newBoxResized.Controls.Add(noButtonResize);
msgResized.Show();
}
private void YesButtonResizeClicked(object o, EventArgs sEA)
{
this.buttonClickResult = "true";
this.newBoxResized.Close();
}
private void noButtonResizeClicked(object o, EventArgs sEA)
{
this.buttonClickResult = "false";
this.newBoxResized.Close();
}
private void buttonRestoreDefaults_Click(object sender, EventArgs e)
{
YesNoNewMessageBox("Restore Defaults?", "Restore Defaults?", "Yes", "No");
if (this.buttonClickResult == "true")
this.restoreDefaults();
}
My problem is that after hitting yes and closing the form that pops up, buttonClickResult is not seen as true and therefore the restore default function I am calling is not called. Only when clicking on the "RestoreDefaults" button again is the function called. So, it seems that the onclick event for buttonRestoreDefaults_Click isn't reconizing the onclick for the yes or no buttons in the form that popups until clicking on it again. Is there a way around this or some sort of implementation to fix this? Thank you.
Also, here is the code for the class. I was thinking about using delegates and event handlers, but I am not sure if I actually need that since what I have works, but just doesn't update the variable on closing correctly:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
public class YesNoMessageBoxResized : Form
{
private Label labelMessage;
//no default button specified
public YesNoMessageBoxResized(string title, string message, string buttonYes, string buttonNo)
{
InitializeComponent();
this.Text = title;
this.labelMessage.Text = message;
this.Deactivate += MyDeactivateHandler;
}
public YesNoMessageBoxResized()
{
InitializeComponent();
}
private void InitializeComponent()
{
this.labelMessage = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// labelMessage
//
this.labelMessage.AutoSize = true;
this.labelMessage.Font = new System.Drawing.Font("Microsoft Sans Serif", 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.labelMessage.Location = new System.Drawing.Point(12, 31);
this.labelMessage.Name = "labelMessage";
this.labelMessage.Size = new System.Drawing.Size(165, 29);
this.labelMessage.TabIndex = 3;
this.labelMessage.Text = "labelMessage";
//
// YesNoMessageBoxResized
//
this.ClientSize = new System.Drawing.Size(572, 268);
this.Controls.Add(this.labelMessage);
this.Name = "YesNoMessageBoxResized";
this.ResumeLayout(false);
this.PerformLayout();
}
protected void MyDeactivateHandler(object sender, EventArgs e)
{
this.Close();
}
public delegate void buttonYes_ClickResultEvent(object o, EventArgs sEA);
public event buttonYes_ClickResultEvent choiceResult;
}
public class buttonYes_ClickResultEvent : EventArgs
{
public buttonYes_ClickResultEvent(bool choice)
{
this.buttonResult = choice;
}
public bool buttonResult;
}
**I posted this on codereview, but then they told me to post it here since it deals with solving a problem.
just for a test, try using a global variable and set that to true within your yesbuttonresizedclicked event.
something like
public static bool yestest = false;
private void YesButtonResizeClicked(object o, EventArgs sEA)
{
yestest = true;
}
I sort of fixed it by adding a function that had the if statement withing the other button events. I am open to other solutions though:
private YesNoMessageBoxResized newBoxResized;
private string buttonClickResult;
public void YesNoNewMessageBox(string title, string message,string buttonYes, string buttonNo)
{
YesNoMessageBoxResized msgResized = new YesNoMessageBoxResized(title, message, buttonYes, buttonNo);
msgResized.StartPosition = FormStartPosition.CenterScreen;
msgResized.TopMost = true;
Button yesButtonResize = new Button();
Button noButtonResize = new Button();
//yes button
yesButtonResize.Text = buttonYes;
yesButtonResize.Size = new Size(150, 80);
yesButtonResize.Font = new Font("Arial", 26);
yesButtonResize.Location = new Point(100, 150);
//no button
noButtonResize.Text = buttonNo;
noButtonResize.Size = new Size(150, 80);
noButtonResize.Font = new Font("Arial", 26);
noButtonResize.Location = new Point(300, 150);
//make a copy of the current form
newBoxResized = msgResized;
//eventhandlers
yesButtonResize.Click += YesButtonResizeClicked;
noButtonResize.Click += noButtonResizeClicked;
newBoxResized.Controls.Add(yesButtonResize);
newBoxResized.Controls.Add(noButtonResize);
newBoxResized.Show();
}
private void YesButtonResizeClicked(object o, EventArgs sEA)
{
this.buttonClickResult = "true";
this.DoIfStatement();
this.newBoxResized.Close();
}
private void noButtonResizeClicked(object o, EventArgs sEA)
{
this.buttonClickResult = "false";
this.DoIfStatement();
this.newBoxResized.Close();
}
private void DoIfStatement()
{
if (buttonClickResult == "true")
this.restoreDefaults();
}
private void buttonRestoreDefaults_Click(object sender, EventArgs e)
{
YesNoNewMessageBox("Restore Defaults?", "Restore Defaults?", "Yes", "No");
}
I think I need it to be more modular though. I don't always want the same if statement there. So, I don't always want to be a yes and no with regards to restore defaults. I may want it to do something else with another function call and have yes and no buttons do something else.
You can just use MessageBox to do this for you:
if (MessageBox.Show("Yes or no?", "", MessageBoxButtons.YesNo)
== DialogResult.Yes)
You could change the form to a modal dialog form. Make the Accept and Cancel buttons properties equal the appropriate button. Then change the dialog result of each button to the appropriate value. Now when you use the ShowDialog the form will return the appropriate DialogResult.
I create a winform application that contains 3 textbox (pcno, pcname and pcipadd), one listbox that is using a datasource and one button to add new item. I'm having a trouble to add an item to my listbox. I'm using this code on the add item button:
_pcno.Add(new PCNo() { PCNO = pcno.Text,
PCNAME = pcname.Text,
IPADDRESS = pcipadd.Text });
The code above adds the new item successfully, but the selected item in the listbox also been updated.
In details, I currently have a "PCN01" on my listbox. Then I go to my textbox (pcno.text) then write new value (example "PC02") and click the button to add item .What happens is the item is added but the "PC01" are also getting updated to "PC02". After reloading the form (re-open) all change back to normal, "PC01" with its value and "PC02" with its value. I just don't want the selected item on the listbox getting update while adding the new item. Any ideas?
Ok, to put this simplly, this is what I'm trying to do, you can try it, if you add new item the selected item also getting updated:
using System;
using System.ComponentModel;
using System.Windows.Forms;
namespace PCListing
{
public partial class Form1 : Form
{
private BindingList<mylist> _pcno;
private ListBox listBox1;
private TextBox pcno;
private TextBox pcname;
private Button btnAdd;
public Form1()
{
InitializeComponent();
FlowLayoutPanel layout = new FlowLayoutPanel();
layout.Dock = DockStyle.Fill;
Controls.Add(layout);
listBox1 = new ListBox();
layout.Controls.Add(listBox1);
pcno = new TextBox();
layout.Controls.Add(pcno);
pcname = new TextBox();
layout.Controls.Add(pcname);
btnAdd = new Button();
btnAdd.Click += btnAdd_Click;
btnAdd.Text = "Add Item";
layout.Controls.Add(btnAdd);
Load += new EventHandler(Form1_Load);
}
private void Form1_Load(object sender, EventArgs e)
{
_pcno = new BindingList<mylist>();
_pcno.Add(new mylist() { pcno = "1", pcname = "PC01" });
_pcno.Add(new mylist() { pcno = "2", pcname = "PC02" });
listBox1.DisplayMember = "pcno";
listBox1.DataSource = _pcno;
pcno.DataBindings.Add("Text", _pcno, "pcno");
pcname.DataBindings.Add("Text", _pcno, "pcname");
}
private void btnAdd_Click(object sender, EventArgs e)
{
_pcno.Add(new mylist() { pcno =pcno.Text, pcname = pcname.Text });
}
public class mylist
{
public string pcname { get; set; }
public string pcno { get; set; }
}
}
}
The problem is caused by TextBox databindings.
pcno.DataBindings.Add("Text", _pcno, "pcno");
pcname.DataBindings.Add("Text", _pcno, "pcname");
In that form DataSource is updated when you edit values in text boxes.
You might consider changing those lines to:
pcno.DataBindings.Add("Text", _pcno, "pcno", false, DataSourceUpdateMode.Never);
pcname.DataBindings.Add("Text", _pcno, "pcname", false, DataSourceUpdateMode.Never);