Dynamically Created Winform Comboboxes all selecting the same value - c#

I'm creating a winform application wit C# and VS 2010 Ultimate. I'm populating a flowlayoutpanel with dynamically created comboxes, all databound to the same bindinglist.
When I run the application, it adds the comboxes correctly but when I select an item on one combobox, all the others are updated with the same selection.
What am I doing wrong?
Thanks very much for any help received.
J.
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 TestCompleteForm
{
public partial class Form1 : Form
{
private int comboBoxIndex = 0;
List<string> Existingfiles;
BindingList<string> ExistingSystemsList;
List<string> Selectedfiles;
BindingList<string> SelectedSystemsList;
BindingList<string> ListOfLanguages = new BindingList<string>();
BindingList<string> ListOfSQLServers = new BindingList<string>();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
DirectoryInfo dinfo = new DirectoryInfo(#"C:\Hosts");
FileInfo[] Files = dinfo.GetFiles("*.txt");
Existingfiles = new List<string>();
foreach (FileInfo file in Files)
{
Existingfiles.Add(Path.GetFileNameWithoutExtension(file.Name));
}
ExistingSystemsList = new BindingList<string>(Existingfiles);
lbAvailableSystems.DataSource = ExistingSystemsList;
Selectedfiles = new List<string>();
SelectedSystemsList = new BindingList<string>(Selectedfiles);
lbSelectedSystems.DataSource = SelectedSystemsList;
//Creat list of languages
var txtLanguages = File.ReadAllLines(#"C:\Languages\Languages.txt");
foreach (var s in txtLanguages) ListOfLanguages.Add(s);
//Creat list of sql servers
var txtSqlServers = File.ReadAllLines(#"C:\SQL Servers\sql-servers.txt");
foreach (var s in txtSqlServers) ListOfSQLServers.Add(s);
}
private void TabControl1_Click(object sender, EventArgs e)
{
if (tabControl1.SelectedTab.Name.ToString() == "page2")
{
while (flowLayoutPanel1.Controls.Count > 0)
{
var ControlToRemove = flowLayoutPanel1.Controls[0];
flowLayoutPanel1.Controls.Remove(ControlToRemove);
ControlToRemove.Dispose();
}
//flowLayoutPanel1.Controls.Clear();
foreach (string StrSystem in SelectedSystemsList)
{
Label lNewSystem = new Label();
lNewSystem.Text = StrSystem;
flowLayoutPanel1.Controls.Add(lNewSystem);
//Add combobox for languages
ComboBox cbLanguages = new ComboBox();
cbLanguages.Name = "cbLanguages" + comboBoxIndex.ToString();
cbLanguages.DataSource = ListOfLanguages;
flowLayoutPanel1.Controls.Add(cbLanguages);
//Add combobox for database servers
ComboBox cbSqlServers = new ComboBox();
cbSqlServers.Name = "cbSqlServers" + comboBoxIndex.ToString();
cbSqlServers.DataSource = ListOfSQLServers;
flowLayoutPanel1.Controls.Add(cbSqlServers);
comboBoxIndex++;
}
}
}

Ignore the bindinglist and use ComboBox.Items.Add() instead to add items to the control.

Related

c# windows form System.Runtime.InteropServices.COMException

I am trying to write c # code that automates the process of filling out Word templates. I use DataGridView because I don't know how many types of elements I need to replace. Upon completion of work, it throws an error System.Runtime.InteropServices.COMException: "The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)" thanks
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;
using Word = Microsoft.Office.Interop.Word;
namespace Anya_v_0._8
{
public partial class Form1 : Form
{
//-------------------struct---------------------//
public struct name
{
public string teg;
public string change;
public name(String _teg, string _change)
{
teg = _teg;
change = _change;
}
}
//----------------------------------------//
List<name> names = new List<name>();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//-------------------table------------//
DataTable table = new DataTable();
table.Columns.Add("Тэг", typeof(string));
table.Columns.Add("Название", typeof(string));
for (int i = 0; i < names.Count; i++)
{
table.Rows.Add(names[i].teg, names[i].change);
}
dataGridView1.DataSource = table;
//-------------------------------//
}
private void click_start_Click(object sender, EventArgs e) {
String vhod = inputBox.Text;
String uhod = outputBox.Text;
var wordApp = new Word.Application();
wordApp.Visible = false;
var wordDocument = wordApp.Documents.Open(vhod);
for (int i = 0; i < dataGridView1.RowCount; i++)
{
for (int j = 0; j < dataGridView1.ColumnCount; j++)
{
object a = dataGridView1.Rows[i].Cells[j].ToString();
object b = dataGridView1.Rows[i+1].Cells[j].ToString();
ReplaceWordStub(a, b, wordDocument);
}
}
wordDocument.SaveAs(uhod);
}
private void ReplaceWordStub(object stubToReplace, object text, Word.Document wordDocument)
{
var range = wordDocument.Content;
range.Find.ClearFormatting();
range.Find.Execute(FindText: stubToReplace, ReplaceWith: text);
}
public void inputBox_TextChanged(object sender, EventArgs e)
{
}
}
}
Your solution needs to have the word installed to work, you could use OpenXML instead.
But considering you want to keep this dependency on Word, check if the Remote Procedure Call is started and running on your windows services

why can't I add a new List object in button event

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();
}
}
}

C# Open listView Item from treeView item location

I'm needing a way to allow the files that are displayed in the ListView to be opened. The Items In the ListView are displayed from the TreeView. Take a look at my code below to see in more detail.
Code for this form
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 OSTP
{
public partial class User1FileExplorer : Form
{
public User1FileExplorer()
{
InitializeComponent();
PopulateTreeView();
this.treeView1.NodeMouseClick +=
new TreeNodeMouseClickEventHandler(this.treeView1_NodeMouseClick);
}
private void User1FileExplorer_Load(object sender, EventArgs e)
{
}
private void PopulateTreeView()
{
TreeNode rootNode;
DirectoryInfo info = new DirectoryInfo(#"C:\Users\Oliver\Documents\.OSTP\User1\Files\Documents");
if (info.Exists)
{
rootNode = new TreeNode(info.Name);
rootNode.Tag = info;
GetDirectories(info.GetDirectories(), rootNode);
treeView1.Nodes.Add(rootNode);
}
}
private void GetDirectories(DirectoryInfo[] subDirs,
TreeNode nodeToAddTo)
{
TreeNode aNode;
DirectoryInfo[] subSubDirs;
foreach (DirectoryInfo subDir in subDirs)
{
aNode = new TreeNode(subDir.Name, 0, 0);
aNode.Tag = subDir;
aNode.ImageKey = "folder";
subSubDirs = subDir.GetDirectories();
if (subSubDirs.Length != 0)
{
GetDirectories(subSubDirs, aNode);
}
nodeToAddTo.Nodes.Add(aNode);
}
}
private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
TreeNode newSelected = e.Node;
listView1.Items.Clear();
DirectoryInfo nodeDirInfo = (DirectoryInfo)newSelected.Tag;
ListViewItem.ListViewSubItem[] subItems;
ListViewItem item = null;
foreach (DirectoryInfo dir in nodeDirInfo.GetDirectories())
{
item = new ListViewItem(dir.Name, 0);
subItems = new ListViewItem.ListViewSubItem[]
{new ListViewItem.ListViewSubItem(item, "Directory"),
new ListViewItem.ListViewSubItem(item,
dir.LastAccessTime.ToShortDateString())};
item.SubItems.AddRange(subItems);
listView1.Items.Add(item);
}
foreach (FileInfo file in nodeDirInfo.GetFiles())
{
item = new ListViewItem(file.Name, 1);
subItems = new ListViewItem.ListViewSubItem[]
{ new ListViewItem.ListViewSubItem(item, "File"),
new ListViewItem.ListViewSubItem(item,
file.LastAccessTime.ToShortDateString())};
item.SubItems.AddRange(subItems);
listView1.Items.Add(item);
}
listView1.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
}
}
}
As you can see from my code I use a TreeView to select the directory for the files then the ListView to display the files inside of the directory.
I would like it so when the user double clicks the file in the ListView it opens. And when I say open I'm not meaning open a text file as such. So lets say the user double clicks text file 1 in the ListView, I would like it to show User1TextFile1.cs. This is because the text files are loaded into a text box.
I know this is a little complicated, so If I have missed anything please drop a comment.
Thanks.
UPDATE
http://pastebin.com/BgVdLavL
UPDATE2
When I add MessageBox.Show("" + lvHti);
To find out which ListViewItem was clicked or doubleclicked use the MouseClick or the MouseDoubleClick event.
Here you can either code simply:
ListViewItem lvItem = null;
if (listView1.SelectedItems.Count > 0)
lvItem = listView1.SelectedItems[0];
provided the ListView has MultiSelect = false.
If you allow multiple selections you need to do a HitTest to find out where the user has clicked:
ListViewItem lvItem = null;
ListViewHitTestInfo lvHti = listView1.HitTest(e.Location);
if (lvHti.Item != null) lvItem = lvHti.Item;
Now you can access the Item and/or its SubItems to process the choice.

How can i save settings of my app to a text file and read them back on load?

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;

C# form instantly closing

All of a sudden my form window has begun to close as soon as the application is launched. There's nothing in the output window that gives a hint as to what could be causing it and there are no errors thrown at me either. Does anybody have any ideas?
I've provided to form's class.
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 ProjectBoardManagement {
public partial class CreateBoard : Form {
Functions funcs = new Functions();
public CreateBoard() {
InitializeComponent();
}
private void CreateBoardButton_Click(object sender, EventArgs e) {
String BoardName = BoardNameText.Text;
String Pages = "";
String Labels = "";
foreach (ListViewItem i in PageNameList.Items) {
Pages = (Pages + i.Name.ToString() + ",");
}
foreach (ListViewItem i in LabelNameList.Items) {
Labels = (Labels + i.Name.ToString() + ",");
}
String BoardFile = ("board_" + BoardName + ".txt");
funcs.SaveSetting(BoardFile, "name", BoardName);
funcs.SaveSetting(BoardFile, "pages", Pages);
funcs.SaveSetting(BoardFile, "labels", Labels);
FormManagement.CreateBoard.Hide();
FormManagement.BoardList.LoadBoardList();
}
private void PageNameButtonAdd_Click(object sender, EventArgs e) {
String pagename = PageNameText.Text;
if (pagename != "") {
PageNameList.Items.Add(pagename);
}
PageNameText.Text = "";
}
private void LabelNameButtonAdd_Click(object sender, EventArgs e) {
String labelname = LabelNameText.Text;
if (labelname != "") {
LabelNameList.Items.Add(labelname);
}
LabelNameText.Text = "";
}
}
}
Obvious first thing to do - run it in Debug mode and stop execution on all exceptions. This should give you enough information on how to go from there.
Otherwise Functions funcs = new Functions(); looks suspicious.

Categories