I've created a ListView in a new WPF window and also a function that populates the ListView when it is called. This function just takes the URL of my web server where I've stored the data, increments the "id" and gets the data and stores it in the ListView. Therefore it populates the ListView with a certain number of items.
The problem I'm facing is that I want to add two buttons, ON & OFF, to each ListView item as it gets populated programmatically. i.e, if 16 items are added, I want 2 buttons for each item, and if it's 12 items, the similar procedure. Here's my code:
namespace user_login
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
Window1 W = new Window1();
public MainWindow()
{
InitializeComponent();
}
public void populate()
{
int i;
int num = 16;
for (i = 1; i <= num; i++)
{
string val = Convert.ToString(i);
string currentUrl = "http://xpleria.com/devices.php?query=dev&id=";
string newUrlWithChangedSort = ReplaceQueryStringParam(currentUrl, "id", val);
string result = getcontent(newUrlWithChangedSort);
W.list1.Items.Add(result);
}
}
public string getcontent(string URL)
{
string content = "";
// Get HTML data
WebClient client = new WebClient();
try
{
content = client.DownloadString(URL);
}
catch (Exception)
{
System.Windows.Forms.MessageBox.Show("No Connection detected!!!");
}
return content;
}
public static string ReplaceQueryStringParam(string currentPageUrl, string paramToReplace, string newValue)
{
string urlWithoutQuery = currentPageUrl.IndexOf('?') >= 0
? currentPageUrl.Substring(0, currentPageUrl.IndexOf('?'))
: currentPageUrl;
string queryString = currentPageUrl.IndexOf('?') >= 0
? currentPageUrl.Substring(currentPageUrl.IndexOf('?'))
: null;
var queryParamList = queryString != null
? HttpUtility.ParseQueryString(queryString)
: HttpUtility.ParseQueryString(string.Empty);
if (queryParamList[paramToReplace] != null)
{
queryParamList[paramToReplace] = newValue;
}
else
{
queryParamList.Add(paramToReplace, newValue);
}
return String.Format("{0}?{1}", urlWithoutQuery, queryParamList);
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
string user = textbox1.Text;
string password = textbox2.Password;
string currentUrl = "http://xpleria.com/login.php?query=login&user=wcam&pass=wireless";
string newUrlWithChangedSort = ReplaceQueryStringParam(currentUrl, "user", user);
string newUrl = newUrlWithChangedSort;
string FinalUrl = ReplaceQueryStringParam(newUrl, "pass", password);
string result= getcontent(FinalUrl);
string value = result.Substring(0, 8);
string invalid = "xpleria0";
string valid = "xpleria1";
if (value.Equals(invalid))
{
System.Windows.MessageBox.Show("The Username and/or Password you have entered is invalid, please try again");
}
else if (value.Equals(valid))
{
string sessionID = result.Substring(8, 32);
System.Windows.MessageBox.Show("HI, WELCOME CLETA");
this.Close();
using (new user_login.loading.PleaseWait(this.Location))
{
W.Show();
populate();
}
}
}
public System.Drawing.Point Location { get; set; }
}
}
I'm going to recommend you take a step back and start giving some serious consideration to organizing your code. I realize this isn't an answer to the question you asked but it is the answer to the question you should be asking.
First of all, all code relating to the retrieval of these items from the URL should be moved into a class of some kind. This class should accept the URL string as a constructor parameter and gather all the appropriate data. You should then create another class which you will use to populate with the data for each individual item and then expose this list. By the time you're done the code in your window should little more complex than:
var ItemsGetter = new ItemsGetter(URL);
foreach(var Item in ItemsGetter.Items)
{
// Populate the ListView
}
Once you're done with that I recommend you create a UserControl. User controls are extremely useful in situations where you need to represent a dynamic number of data entities each with their own set of controls which allow operations to be performed on each one. You should create a UserControl with a label and the two buttons you need. The UserControl's constructor should expect a parameter of the data type you created to represent each one of your classes. From there you can have the buttons operate on the data type as necessary.
Finally, you'll probably need a way to have the UserControl interact with the Window. Say for example one of your buttons is "Delete". You'd probably want the item to disappear from the list once the operation is complete. Don't be tempted to tie in your control with the Window by passing it as a parameter or something. Instead, read up on Action events and learn how you can create an event on the user control which you bind in the foreach loop of the Window when you're populating the list view. When the UserControl has completed the delete operation triggered by the button you can raise the UserControl's event which will prompt the Window to remove the control from the List View.
Last but not least, NAME YOUR CONTROLS.
Hopefully this helps.
Related
I have a WinForms Dialog with 2 ListBox controls. In the application under test, doubleClicking any items in one of the listbox controls (I'll call this the CONTROL LISTBOX) results in selecting the matching item in the other listbox (SLAVE LISTBOX).
My test causes multiple entries to be made in the CONTROL LISTBOX. The test then performs a ListBox.SelectedItem.DoubleClick() on each of the CONTROL lISTBOX items, comparing the ListBox.SelectedItemText from both listbox controls.
In the application UI, this ALWAYS works, but the test of the call to ListBox.SelectedItemText for SLAVE LISTBOX returns the text matching what is slected in the UI correctly ONLY on the initial iteration of the doubleclick\compare.
Can anybody help me figure out what I'm doing wrong? Thanks!
Here is my code:
public bool SelectMainEventViaErrorEvent(int eventIdx)
{
bool bSuccess = false;
errorEvents.Items.Select(eventIdx);
System.Threading.Thread.Sleep(1000);
errorEvents.Items.SelectedItem.DoubleClick();
System.Threading.Thread.Sleep(1000);
if (eventIdx > 0)
{
IVScrollBar vertScroll = mainEvents.ScrollBars.Vertical;
vertScroll.ScrollDownLarge();
}
if (errorEvents.SelectedItemText == mainEvents.SelectedItemText)
{
bSuccess = true;
}
log.Info($"SelectMainEventViaErrorEvent({eventIdx}) selected error event = {errorEvents.SelectedItemText}");
log.Info($"SelectMainEventViaErrorEvent({eventIdx}) selected main event = {mainEvents.SelectedItemText}");
return bSuccess;
}
As you can see, by the following image, the text in both list boxes are identical. However, the call to ListBox.SelectedItemText for the top listbox (SLAVE LISTBOX) returns the value from the first iteration, which matched the first item in the bottom listbox (CONTROL LISTBOX) during the first iteration of the doubleclick/compare.
Proof that the text of the selected listbox items match
Comparing with plain text is bad idea since "Text" != "Text ". What you could use in yor case is DisplayMember and ValueMember properties.
I will demonstrate it for you with manually populating listboxes but you do it from database or however you do it.
First of all create class that will store your values and it's ID's. I usually create it like this (so i am able to use that class later for something else)
public class Int_String
{
public int _int { get; set; } // Important to be declared like properties and not like variables
public string _string { get; set; }
}
Now let's populate our listbox like this:
public YourForm()
{
List<Int_String> list = new List<Int_String>();
list.Add(new Int_String { _int = 1, _string = "Some text" }); // I am populating it manually but you will populate it from DB or somewhere else
list.Add(new Int_String { _int = 2, _string = "Some other text" });
list.Add(new Int_String { _int = 3, _string = "One more text" });
// Now when we have list we need to bind it to our listbox.
// IMPORTANT!!!!!
// Display member and Value member properties SHOULD be able to be added before and after assigning datasource to control (like combobox) BUT for some reason on listbox it only works when you assign it AFTER you bind your datasource to listbox.
// If you ever work with other controls and use these values, ALWAYS declare display member and value member BEFORE you bind datasource. Why? For now let's just say it is much faster but explanation is for other question
myListBox1.DataSource = list;
myListBox1.DisplayMember = "_string"; // When you start typing .DisplayMember, you will not get that property in recommendation since it is hidden so do not think there is not that property there.
myListBox1.ValueMember = "_int"; // Same as above
}
Now when you populate listbox like this and second one on same way with same id's you could simply do if(listbox1.SelectedValue == listbox2.SelectedValue) and compare them even if their text is not equal but id is.
BONUS:
Also what you can do is expand class like this:
public class Int_String
{
public int _int { get; set; }
public string _string { get; set; }
public string SomethingOther = "AsD";
public bool IsTrue()
{
return true;
}
}
then bind it on same way and do this:
Int_String item = listbox1.SelectedItem as Int_String;
bool check = item.IsTrue();
MessageBox.Show(item.SomethingOther);
So basically you bind whole class for each item in listbox, display to user one of the variables (in our case _string), set ValueMember to other unique variable so it is easy to search whole listbox and when needed get whole class from that item.
I wasn't ever able to get this working by iterating forward through the errorEvent listbox in my automated test code, but it DOES work when iterating backwards through the errorEvent listbox.
Calling code:
for (int i = eventViewer.GetErrorEventsCount() - 1; i >= 0; i--)
{
bResult = eventViewer.SelectMainEventViaErrorEvent(i);
if (!bResult)
{
break;
}
System.Threading.Thread.Sleep(2000);
}
Verification Code:
public bool SelectMainEventViaErrorEvent(int eventIdx)
{
bool bSuccess = false;
DisableToolTips(true);
errorEvents.Select(eventIdx);
errorEvents.SelectedItem.DoubleClick();
System.Threading.Thread.Sleep(1000);
log.Info($"SelectMainEventViaErrorEvent({eventIdx}) selected error event = {errorEvents.SelectedItemText}");
log.Info($"SelectMainEventViaErrorEvent({eventIdx}) selected main event = {mainEvents.SelectedItemText}");
if (errorEvents.SelectedItemText == mainEvents.SelectedItemText)
{
bSuccess = true;
}
return bSuccess;
}
I'm relatively new to C# and have spent an inordinate amount of time trying to figure this out myself with no luck. Hoping you guys can help.
I have 2 windows forms. In the first form, the user enters a citation number. I want to take that citation number, search for it in an external text file, and then return all of the data in the row for that citation into separate textboxes.
The text file looks something like this:
S8729936 , 6JXV123 , 10/1/2015 , 10/31/2015 , PAID , 49.5
A7472601 , 2NXP234 , 10/12/2015 , 11/11/2015 , UNPAID , 99
W2041810 , 5JPB345 , 10/19/2015 , 11/18/2015 , UNPAID , 99
And the second form has 6 textboxes. I have it so that the citation number, let's say S8729936 is passed into the first textbox, but I cannot seem to figure out how to then search the text file for S8729936 and give me the rest of the data in the row inside the textboxes.
Here are some examples of things I've tried. I've been copying and pasting and then messing with code all day, so if the details don't seem to match, that's probably the reason.
public Form2(string citation)
{
InitializeComponent();
txtCitation2.Text = citation;
const string FILENAME = #"\Path\ProjectData.txt";
FileStream fsInFile = new FileStream(FILENAME, FileMode.Open, FileAccess.Read);
StreamReader srReader = new StreamReader(fsInFile);
const char CH_DELIM = ',';
string strRecordIn;
string[] strFields;
if (strFields != null)
{
strRecordIn = srReader.ReadLine();
strFields = strRecordIn.Split(CH_DELIM);
txtLicense2.Text = strFields[1];
}
strRecordIn = srReader.ReadLine();
srReader.Close();
fsInFile.Close();
}
No luck there, how about something along the lines of this:
string whole_file = File.ReadAllText(#"Path\ProjectData.txt");
whole_file = whole_file.Replace('\n', '\r');
string[] lines = whole_file.Split(new char[] { '\r' });
int num_rows = lines.Length;
int num_cols = lines[0].Split(',').Length;
string[,] values = new string[num_rows, num_cols];
for (int r = 0; r < num_rows; r++)
{
string[] line_r = lines[r].Split(',');
for (int c = 0; c < num_cols; c++)
{
values[r, c] = line_r[c];
}
}
txtLicense2.Text = lines[1];
Nope. Maybe something along the lines of this:
const string FILENAME = #"C:\Users\rfranklin\Documents\ProjectData.txt";
FileStream fsinfile = new FileStream(FILENAME, FileMode.Open, FileAccess.Read);
StreamReader srReader = new StreamReader(fsinfile);
const string CH_DELIM = " ,";
string strRecordIn;
string[] strFields = new string[10];
string citnum = citation;
bool found = false;
strRecordIn = srReader.ReadLine();
foreach(string x in strFields)
{
if (x == citation)
{
found = true;
break;
}
}
if (found)
{
txtLicense2.Text = strFields[1];
}
Still no luck. And on and on. It seems as though I'm mostly missing how to tell the program what to search for and I am not sure what else to do. Like I said, I've been Googling various ways to do it all day, but I can't seem to make anything work right.
I'm doing this in Visual Studio 2013, if that helps.
Any help would be immensely appreciated. Thanks.
If the number of lines in the CSV file is not too large (I wouldn't know what "too large" is), then you could leverage a few .NET constructs, such as Data Binding and Linq to achieve this.
For starters, I would create a class that implements INotifyPropertyChanged:
namespace Citations
{
public class Citation : INotifyPropertyChanged
{
public static Citation ParseLine(string line)
{
Citation cit = new Citation();
if (string.IsNullOrEmpty(line))
throw new ArgumentException("Invalid argument", nameof(line));
string[] vals = line.Split(',');
if (vals.Length != 6)
throw new ArgumentOutOfRangeException(nameof(line), "Invalid format");
cit.CitationNumber = vals[0].Trim();
cit.PlateNumber = vals[1].Trim();
cit.DateCreated = DateTime.Parse(vals[2].Trim());
cit.DateExpired = DateTime.Parse(vals[3].Trim());
cit.Status = vals[4].Trim();
cit.Amount = Decimal.Parse(vals[5].Trim());
return cit;
}
void RaisePropertyChanged(string prop)
{
if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(prop)); }
}
public event PropertyChangedEventHandler PropertyChanged;
string citationNumber;
public string CitationNumber
{
get
{
return citationNumber;
}
set
{
if (citationNumber != value)
{
citationNumber = value;
RaisePropertyChanged(nameof(CitationNumber));
}
}
}
string plateNumber;
public string PlateNumber
{
get
{
return plateNumber;
}
set
{
if (plateNumber != value)
{
plateNumber = value;
RaisePropertyChanged(nameof(PlateNumber));
}
}
}
DateTime dateCreated;
public DateTime DateCreated
{
get
{
return dateCreated;
}
set
{
if (dateCreated != value)
{
dateCreated = value;
RaisePropertyChanged(nameof(DateCreated));
}
}
}
DateTime dateExpired;
public DateTime DateExpired
{
get
{
return dateExpired;
}
set
{
if (dateExpired != value)
{
dateExpired = value;
RaisePropertyChanged(nameof(DateExpired));
}
}
}
string status;
public string Status
{
get
{
return status;
}
set
{
if (status != value)
{
status = value;
RaisePropertyChanged(nameof(Status));
}
}
}
Decimal amount;
public Decimal Amount
{
get
{
return amount;
}
set
{
if (amount != value)
{
amount = value;
RaisePropertyChanged(nameof(Amount));
}
}
}
}
}
This class is responsible for splitting a line from the CSV file, and converting it to an object of type Citation, which will be used to data bind the textboxes in Form2 later on.
Then in the first Form, I would simply read the file, and using some Linq operators, convert the file to a Dictionary of Citation objects, the key of the Dictionary being the Citation number:
private void button1_Click(object sender, EventArgs e)
{
string[] allLines = File.ReadAllLines("Citations.csv");
Dictionary<string, Citation> dict = allLines.Select(l => Citation.ParseLine(l)).ToDictionary(c => c.CitationNumber, k => k);
Citation cit = dict["W2041810"];
Form2 frm2 = new Form2();
frm2.SetCitation(cit);
frm2.ShowDialog();
}
In the code above, we're using the ToDictionary Linq operator to create a Disctionary from your Citation objects, and the Dictionat key is the Citation number.
Here I'm hardcoding one of the citations for lookup and passing to Form2, which would have a SetCitation method like this:
public void SetCitation(Citation citation)
{
this.citationBindingSource.DataSource = citation;
}
The code to Form2 is a bit difficult to show because I have used the Form designer to setup the data binding for each TextBox, and if I wanted to show that, I'd basically have to show the whole Form2.Designer.cs file.
Instead, I propose to guide you through the process of creating a Project DataSource, then drag & drop the TextBoxes onto Form2 from the Data Sources dialog in Visual Studio.
So, after adding the Citation class to your solution, make sure to compile at leat once so that the "Add data source" wizard will pick that class up as a possible data source.
Then, make sure the Data Sources dialog is displayed by going to View > Other Windows > Data Sources (assuming Visual Studio 2015 here).
From the Data Sources dialog, click the "Add New Data Source button" tolaunch the Data SOurce Configuration Wizard. From the list of possible data sources, you will choose "Object":
Then click the Next button. From the next Wizard step, you will select the Citation class:
and then click the Finish button.
In the Data Sources dialog, you should now have something like this:
From this Data Sources dialog, you can now drag & drop the individual fields onto Form2, which should give you something like this:
You will also notice in the Component tray of Form2, a BindingSource object has been added:
Under the hood, Visual Studio will have set all the Data Binding for your Citation object properties to be displayed in the corresponding TextBox.
This is the "glue" that makes it possible to call Form2.SetCitation() with a Citation object, and have all the fields displayed where they should.
I know this is quite a mouthful to chew on, but believe me, once you understand the principles behind this, you will not want to go back to the kind of spagethi code that you started implementing (no offense, we've all been there).
If you would like me to clarify any specific section of my answer, just let me know, and I'll edit accordingly.
Cheers
A simple winForm version:
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.IO;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
List<string> matchedList = new List<string>();
public Form1(string citation)
{
InitializeComponent();
string filePath = #"C:\Users\rfranklin\Documents\ProjectData.txt";
string[] linesArr = File.ReadAllLines(filePath);
//find matches
foreach(string s in linesArr)
{
if(s.Contains(citation))
{
matchedList.Add(s); //matched
}
}
//output
foreach(string s in matchedList)
{
Console.WriteLine(s); //write to console
//or output to wherever you wish, eg.
//richTextBox.Text += s + "\n";
}
}
}
}
Note that Form1 needs to be called from somewhere else and take in citation argument. To test it standalone, change it to
public Form1()
{
InitializeComponent();
string citation = "S8729936";
The suggestion from #interceptwind did it for me. Inside the //output section of the code he provided, I basically just created a second array from the matched line, with the elements separated by the comma. The code looks like this:
//output
foreach (string s in matchedList)
{
string citationLine = s;
string[] lineData = citationLine.Split(',');
txtLicense2.Text = lineData[1];
txtIssued2.Text = lineData[2];
txtDue2.Text = lineData[3];
txtStatus2.Text = lineData[4];
txtAmount2.Text = lineData[5];
}
This allowed me to put the data in the textboxes I needed. Thank you all for the assistance!
I have a Grid view with two columns that have drop down lists. This drop down lists save as soon as a value is selected. I want to prevent the user from selecting a value in the second drop down list without selecting a value from the first one. So the first drop down list shouldn't be blank.
public static void UpdateMemReasonSecond(int SerNoID, string sel)
{
JobOutturn SerNo = new JobOutturn(SerNoID);
SerNo.MemReasonSecond = sel;
SerNo.MemDate = DateTime.Now;
SerNo.MemUser = CurrentUser.Username;
SerNo.Update();
if (SerNo.MemReason == "" & SerNo.MemReasonSecond != "")
{
throw new Exception("Please fill in first reason");
}
}
Jquery Code:
function UpdateMemReasonSecond(SerNoID, sel) {
PageMethods.UpdateSecondMemReasonUserControl(SerNoID, sel, OnUpdateSuccess, OnUpdateFailReason);
}
So the exception works but the error message that comes up contains a lot of extra lines and not just my message. Is there a way to only display my message?
To use ClientScript inside a static method pass the Page object as a parameter to your static method.Page is not static class.You can not call non static fields inside static method.So you need to pass the page object to your static method as a parameter.
public static void UpdateMemReasonSecond(int SerNoID, string sel ,Page page)
{
JobOutturn SerNo = new JobOutturn(SerNoID);
SerNo.MemReasonSecond = sel;
SerNo.MemDate = DateTime.Now;
SerNo.MemUser = CurrentUser.Username;
SerNo.Update();
if (SerNo.MemReason == "" & SerNo.MemReasonSecond != "")
{
page.ClientScript.RegisterStartupScript(page.GetType(),"alert", "<script>alert('Please fill in first reason');</script>");
}
}
Before I begin, I have researched and can't seem to find anything. Note I am very new to UserControl so this might be why it's proven difficult.
I have a combobox in Form1 which when selected allows the user to change between a choice of 21 languages. I have created a UserControl that contains labels, buttons and checkboxes - adds to a form called Print.
If a user selected French, how would I then implement the UserControl to change language for ALL forms in my project?
UserControl:
I have used a get and set method here for a button. When the language is changed in Form1, I want this button (all elements really) to change.
using System.Windows.Forms;
namespace Print
{
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
public string LabelPreview
{
get
{
return Button_Preview.Text;
}
set
{
Button_Preview.Text = value;
}
}
}
}
Form1:
If string value English is selected in the combobox, call a method - here is where I would like to change language for other forms.
private void ComboBoxLang_SelectedIndexChanged(object sender, EventArgs e)
{
string selectedItem = this.comboBoxLang.GetItemText(this.comboBoxLang.SelectedItem);
if (selectedItem == Language.English)
{
ToEnglish();
}
}
private void ToEnglish()
{
// Cannot actually implement the UserControl, It can't find the method above.
// When I've tried to implement UserControl in Print, it can't seem to find it either.
// I've tried:
// Print.UserControl1.(_LabelPreview doesn't show_);
// ^ It might be the completely wrong thing to do so excuse me.
}
I'm so confused... Do I program in Print (where the UserControl is added) or/and Form1?! I don't want the design to appear in Form1, but just want to let the other forms know what language has been selected.
Note: I have been using Unicode when translating*
How to trigger application-wide language change I described here on your other question Everytime ComboBox is changed (using SelectedIndexChanged) display message in other forms, if opened, of new value
Now, to set controls... One way of doing it is to create Database of phrases with StringId in one table and the StringId, LanguageId, StringValue in another. You would create StringManager object, which will have method GetLanguageSpecificString(stringId, languageId). When language change is triggered, your controls will call GetLanguageSpecificString fro each label you display, etc.
So your data will be like
Table DisplayLanguage
LanguageId Int
LanguageName nvarchar
LanguageCulture varchar
//1, English, us-En
//2, French, fr-Ca
Table DisplayString
StringId Int
//1
//2
//3
Table DisplayStringValue
DisplayStringValueId int
StringId int
LanguageId int
StringValue nvarchar
//1, 1, 1, Person Name
//2, 1, 2, Nome de Persona(or whateever)
Create cache using
"Select * from DisplayStringValue where LanguageId = 1"
And then use Linq or something to select for each control its data from cache because you don't want to hit DB with these for each control
"Select StringValue from DisplayStringValue where StringId = 1 and LanguageId = 1"
Now, combine my other answer with this and you will see that if in your form you have
LanguageChangeObserver.LanguageChanged += MyObserverHandler;
private void MyObserverHandler(languageId)
{
_formLanguage = languageId;
// set your controls
lblFirstName.Text = GetLanguageSpecificString(5, languageId);
lblLastName.Text = GetLanguageSpecificString(6, languageId);
// loop through userControls and pass to them language id
}
It would be good idea if your user controls would derive from the single base class that you create and which has already SetNewLanguage Method, so you could do
foreach (var c in form.controls)
{
MyControlBase currControl = c as MyControlBase;
if (currControl != null) currControl.SetNewLanguage(languageId);
}
So I've come up with a solution that works for me! I've copied across from the Printer.cs form where I have used a parameter to represent the language chosen, initiated strTextBox to equal label1 and included an if statement to see if the language is English (also working with UserControl to get the value of labels etc.).
Printer
public Printer(string strTextBox)
{
InitializeComponent();
label1.Text = strTextBox;
if (label1.Text == Language.English)
{
UserControl111.Label_Option_Multi = "Please select an option:"; //Simple test
}
}
Form1
private void Print_Click(object sender, EventArgs e)
{
string selectedItem = this.ComboBox_Lang.GetItemText(this.ComboBox_Lang.SelectedItem);
Printer p = new Printer(selectedItem);
p.Show();
}
UserControl
public string Label_Option_Multi
{
get
{
return Label_Option.Text;
}
set
{
Label_Option.Text = value;
}
}
As a result, if I select English in Form1.s then open up Printer.cs, the label displays English and translates accordingly.
You have to do it same way as for any other control. Imagine you have created your TextBox and now want all your textboxes in the project on each form to do something.
Obviously, you have to get a list of such controls somehow. One approach is to use Application.Forms to iterate through everything. Other is to register your control (add to a list) every time when it's created or shown or what_you_need and de-register (remove from a list) otherwise.
I have a method that adds items to my listbox called refreshInterface which is called as soon as the programe starts, adding names of homeforms in the listbox using the FormItems class, here is the rereshInterface method below
public void refreshInterface()
{
//int number = 0;
foreach (DataSet1.xspGetAnalysisUsageTypesRow homeForms in myDataSet.xspGetAnalysisUsageTypes)
{
var forms = new FormItems(homeForms);
listBox1.Items.Add(forms);
}
}
The FormItems class is this below
public class FormItems
{
public DataSet1.xspGetAnalysisUsageTypesRow types { get; set; }
public FormItems(DataSet1.xspGetAnalysisUsageTypesRow usageTypes)
{
types = usageTypes;
}
public override string ToString()
{
// returns the rows that are relating to types.xlib_ID
var libtyps = types.GetxAnalysisUsageRows();
var cnt = 0;
foreach (DataSet1.xAnalysisUsageRow ty in libtyps)
{
//returns true if ty is null
bool typeNull = ty.Isxanu_DefaultNull();
// if its false, if xanu_Default is set
if (!typeNull)
{
cnt += 1;
}
}
var ret = String.Format("set {0} [Set: {1}]", types.xlib_Desc, cnt);
//return this.types.xlib_Desc;
return ret;
}
}
Each listbox (the listbox is on the left of the homeform) item has a number of reports that can be added to it, so for instance, i select an homeform from my listbox, there are 12 textboxes on the right hand side and each textbox has a pair of buttons which are Browse and Clear. If I click on the browse button a new form appears, and i select a report from that form and add it to a particular textbox, the count for that homeform should update, and i clear a textbox for a particular homeform, the count should also update.
At the moment when i debug the application, it shows me the count of each Homeform depending on the amount of reports added to the homeform, but while the programe is running, if i add a new report to a homeform, the count does not update until i restart the debug session. I was told about using a Databinding method but not sure of how i could use it here
How do i ge my listbox item to update ?
You should probably look into binding. Here is a good place to start:
http://www.codeproject.com/Articles/140621/WPF-Tutorial-Concept-Binding
If you want a GUI to respond to data changes then binding is your best friend.
You should bind List Box component source to Observable Collection, every update you do to Observable Collection will update List Box data.
Might not be exact but should give you an idea.
public void refreshInterface()
{
Dictionary<int,string> items = new Dictionary<int,string>();
//int number = 0;
foreach (DataSet1.xspGetAnalysisUsageTypesRow homeForms in myDataSet.xspGetAnalysisUsageTypes)
{
var formitem = new FormItems(homeForms);
items.Add(formitem.someprop, formitem.toString());
}
listbox.DataSource = items;
listbox.DisplayMember = "Value";
listbox.ValueMember = "Key";
}