I have a form with all button, label, I plan to make multi-language support by using INI files. I created Lang Class to hold value, if user change language, on-the-fly update without require restart the program.
my current code:
private void LangGet(string LangID)
{
IConfigSource Lng = new IniConfigSource(Globals.Path.FolderLang + "\\" + LangID + ".ini");
// Set
var g = Lng.Configs["general"];
Lang.Id.General.OK = g.GetString("OK");
Lang.Id.General.Cancel = g.GetString("Cancel");
Lang.Id.General.Error = g.GetString("Error");
...
Lang.Id.General.lblStart = g.GetString("lblStart");
...
what I wanted code more efficient, but I dont know how...
IConfigSource Lng = new IniConfigSource(Globals.Path.FolderLang + "\\" + LangID + ".ini");
var g = Lng.Config["general"];
forloop ( ... )
{
item = g.GetString(item);
}
if more powerful
IConfigSource Lng = new IniConfigSource(Globals.Path.FolderLang + "\\" + LangID + ".ini");
forloop ( ... )
{
forloop ( ... )
{
TheName = Lng.Config[TheClass].GetString(TheName);
}
}
After load INI loaded to Variable, time to control text get Variable value
forloop ( control )
{
forloop ( class )
{
if ( control name contain btn )
{
item.Text = Lng.Configs[TheClass].GetString(item.name?);
}
if ( control name contain lbl )
{
item.Text = Lng.Configs[TheClass].GetString(item.name?);
}
// So On...
I found my answer... so I answer my self,
using Ini-parser instead of Nini...
Make multi-language using INI file, allow language to be edited after compiled, easy to do correction.
Instead write code every control, use loop to do their job
CreateLang(); will scan all your form and it's child, using control Name as Ini Key
LoadLang(); will scan all your form control, once Ini Key equal control name, Value will apply to control.
During designing, all control must be change to {0} or multi-line {0}{1}{2}
Code:
private void frmMain_Load(object sender, EventArgs e)
{
CreateLang(); // Create new empty language
//LoadLang(); // Load language, GUI must use {0} {1} ... as place-holder
}
private void LoadLang()
{
var parser = new FileIniDataParser();
IniData data = parser.ReadFile("eng.ini");
Control ctrl = this;
do
{
ctrl = this.GetNextControl(ctrl, true);
if (ctrl != null)
if (ctrl is Label ||
ctrl is Button ||
ctrl is TabPage ||
ctrl is CheckBox)
if (data["Root"][ctrl.Name].Contains('|')) // Character | donated by New-Line, \n
ctrl.Text = String.Format(ctrl.Text, data["Root"][ctrl.Name].Split('|'));
else
ctrl.Text = String.Format(ctrl.Text, data["Root"][ctrl.Name]);
} while (ctrl != null);
}
private void CreateLang()
{
if (System.IO.File.Exists("eng.ini"))
System.IO.File.WriteAllText("eng.ini", "");
else
System.IO.File.WriteAllText("eng.ini", "");
var parser = new FileIniDataParser();
IniData data = parser.ReadFile("eng.ini");
data.Sections.AddSection("Info");
data.Sections["Info"].AddKey("Name", "Anime4000");
data.Sections["Info"].AddKey("Version", "0.1");
data.Sections["Info"].AddKey("Contact", "fb.com/anime4000");
string main = "Root";
data.Sections.AddSection(main);
Control ctrl = this;
do
{
ctrl = this.GetNextControl(ctrl, true);
if (ctrl != null)
if (ctrl is Label ||
ctrl is Button ||
ctrl is TabPage ||
ctrl is CheckBox ||
ctrl is GroupBox)
data.Sections[main].AddKey(ctrl.Name, "");
} while (ctrl != null);
parser.WriteFile("eng.ini", data);
}
Related
I'm creating a webapp to control some lights in my house. I can't understand why after firing the Event void, the image is not updating; while if i fire it from a button it is actually changing.
I have tried this so far, using KNX.Net libraries
...
public void Event(string address, string state)
{
if (address.Equals(CH03LightOnOffAddressStatus) || address.Equals(CH04LightOnOffAddressStatus))
{
System.Diagnostics.Debug.WriteLine("New Event: device " + address + " has status (" + state + ") --> " + _connection.FromDataPoint("9.001", state));
}
else if (
address.Equals(CH01LightOnOffAddressStatus) ||
address.Equals(CH02LightOnOffAddressStatus)
)
{
var data = string.Empty;
if (state.Length == 1)
{
data = ((byte)state[0]).ToString();
}
else
{
var bytes = new byte[state.Length];
for (var i = 0; i < state.Length; i++)
{
bytes[i] = Convert.ToByte(state[i]);
}
data = state.Aggregate(data, (current, t) => current + t.ToString());
}
System.Diagnostics.Debug.WriteLine("New Event: device " + address + " has status --> " + data);
condition = data;
nowAddress = address;
}
if (condition == "1")
{
Image1.ImageUrl = #"\Res\Call.png";
}
else
{
Image1.ImageUrl = #"\Res\Bomb.png";
}
}
...
While if i fire it like this, the image is changing indeed
...
private void CH01LightOn()
{
_connection.Action(CH01LightOnOffAddress, true);
Thread.Sleep(500);
if (condition == "1")
{
Image1.ImageUrl = #"\Res\Call.png";
}
else
{
Image1.ImageUrl = #"\Res\Bomb.png";
}
}
...
I just need the images to be changing after the event is fired.
Thank you in advance.
This is probably a threading issue. If the Event method is not called on the UI thread, you cannot access your WinForms controls directly, but have to use Control.Invoke.
To try this, replace Image1.ImageUrl = #"\Res\Call.png" by:
if (Image1.InvokeRequired)
{
Image1.Invoke((Action)(() => Image1.ImageUrl = #"\Res\Call.png"));
}
else
{
Image1.ImageUrl = #"\Res\Call.png"
}
I'm trying to make a small application what will be used as a Template Manager. I would like to ask that how to do that in one user form it will show the data in the following way. Will check .xml file and what is inside tags will be shown one under the other. So lets say I have 5 items with this tag, so all 5 will be listed one under another.
I have something like this, but this is opening a new new MessageBox and showing them one by one.
private void button1_Click(object sender, EventArgs e)
{
string Username = System.Security.Principal.WindowsIdentity.GetCurrent().Name.ToString();
var str = Username;
var result = str.Length <= 4 ? "" : str.Substring(4);
string path = $"C:\\Users\\{result}\\Documents
XmlDocument doc = new XmlDocument();
doc.Load(path);
XmlTextReader xtr = new XmlTextReader(path);
while (xtr.Read())
{
if (xtr.NodeType == XmlNodeType.Element && xtr.Name == "name")
{
string string_title = xtr.ReadElementString();
// Console.WriteLine("Name = "+ s1);
MessageBox.Show("Title: " + Environment.NewLine + string_title);
}
}
I have a second from called Form2 for now, I can refer in this way as an example new Form2().Show(); but how do I make the lables on the form change according to what is in the xml file between specific tags?
Try this.
string string_title;
while (xtr.Read())
{
if (xtr.NodeType == XmlNodeType.Element && xtr.Name == "name")
{
string_title += xtr.ReadElementString() + Environment.NewLine;
// Console.WriteLine("Name = "+ s1);
}
}
MessageBox.Show("Title: " + string_title);
Guessing if you are calling form 2 from form 1 on the button click. You can do as below.
Inside button click.
var form2 = new Form2(string_title);
form2.show();
Inside form 2.
string dataFromForm1;
public Form2(string data) {
dataFromForm1 = data;
}
Inside form 2 show method.
public void show(){
MessageBox.Show("Title: " + dataFromForm1);
}
I don't know any other way to explain this apart from providing an image of what I'm doing.
Basically, the Save Cheats button creates a text file that has the information from the 3 textboxes (cheattbox, cheatobox, cheatbbox) numbered respectably. There are 20 total boxes, and to save space only those with data should be saved. Let's say someone wants to save the information from boxes 4, 7, 8 and 13, with those checkboxes checked, I want the text file to only contain information from those given boxes.
Here is the code I have thus far.
public string savemagic(int i)
{
CheckBox tickbox = this.Controls.Find("ccheatcbox" + i.ToString(), true).FirstOrDefault() as CheckBox;
TextBox namebox = this.Controls.Find("ccheatname" + i.ToString(), true).FirstOrDefault() as TextBox;
ComboBox byteselect = this.Controls.Find("ccheatbytebox" + i.ToString(), true).FirstOrDefault() as ComboBox;
TextBox offsetbox = this.Controls.Find("ccheatofsetbox" + i.ToString(), true).FirstOrDefault() as TextBox;
TextBox bytebox = this.Controls.Find("ccheatbytes" + i.ToString(), true).FirstOrDefault() as TextBox;
fu[i] = string.Format("{0} - {1} - {2}\n",namebox.Text, offsetbox.Text, bytebox.Text);
return fu[i];
}
int checkint;
string[] fu = new string[9999];
private void button1_Click(object sender, EventArgs e)
{
SaveFileDialog _SD = new SaveFileDialog();
_SD.Filter = "Text File (*.txt)|*.txt|Show All Files (*.*)|*.*";
_SD.FileName = "Untitled";
_SD.Title = "Save As";
if (_SD.ShowDialog() == DialogResult.OK)
{
foreach(var controls in ccheattab.Controls)
{
if (controls is CheckBox && ((CheckBox)controls).Checked)
{
string tmp = ((CheckBox)controls).Name.Replace("ccheatcbox", "");
checkint = Convert.ToInt32(tmp);
File.WriteAllText(_SD.FileName, savemagic(checkint));
}
}
}
}
You could try just having the checkbox see if it's ticked or not like so
public string savemagic(int i)
{
CheckBox tickbox = this.Controls.Find("ccheatcbox" + i.ToString(), true).FirstOrDefault() as CheckBox;
if (tickbox.Checked) {
TextBox namebox = this.Controls.Find("ccheatname" + i.ToString(), true).FirstOrDefault() as TextBox;
ComboBox byteselect = this.Controls.Find("ccheatbytebox" + i.ToString(), true).FirstOrDefault() as ComboBox;
TextBox offsetbox = this.Controls.Find("ccheatofsetbox" + i.ToString(), true).FirstOrDefault() as TextBox;
TextBox bytebox = this.Controls.Find("ccheatbytes" + i.ToString(), true).FirstOrDefault() as TextBox;
string Cheats= string.Format("{0} - {1} - {2}\n",namebox.Text, offsetbox.Text, bytebox.Text);
return Cheats;
}
return "";
}
https://msdn.microsoft.com/en-us/library/system.windows.forms.checkbox.checked%28v=vs.110%29.aspx
Also, for actually writing to the file, think about using a StreamWriter instead of using File.WriteAllText unless you're going to use a StringBuilder to put these strings together.
This is what happens when you call File.WriteAllText:
Creates a new file, write the contents to the file, and then closes
the file. If the target file already exists, it is overwritten.
For a start it would help you a lot if you abstract your model and have a slight separation form UI, it's just going to confuse you when you are dealing with your business logic.
class CheatObject {
public string Name { get; set; }
public string SelectType { get; set; } // or use enum for this
public string OffsetStr{ get; set; }
public string ByteStr { get; set; }
public ExportToFile() {
// logic to export a CheatModel
}
}
...
Once you have this, it will be much simpler. Your question could be only, what is the best way to get which rows are checked.
Then: foreach (all checked boxes) cheatModelFromRow.ExportToFile();
I have a web browser control embedded in a form. Upon form load it loads a locally stored HTML file. I have implemented a find text functionality to find a particular text in the HTML document loaded in the web browser control. It is working for finding the first occurrence of the word specified.But I want to highlight all the occurrences of the specified word all at once or still better implementing something analogous to "Find Next" function found in various applications. Is it possible to do that for web browser control???
Here's the current code:
private void toolStripButton1_Click(object sender, EventArgs e)
{
string TextToFind;
TextToFind = toolStripTextBox1.Text;
if (webBrowser1.Document != null)
{
IHTMLDocument2 doc = webBrowser1.Document.DomDocument as IHTMLDocument2;
if (doc != null)
{
IHTMLSelectionObject currentSelection = doc.selection;
IHTMLTxtRange range = currentSelection.createRange() as IHTMLTxtRange;
if (range != null)
{
String search = TextToFind.ToString();
if (range.findText(search, search.Length, 2))
{
range.select();
}
}
}
}
}
Thanks.
You will find the the code sample for your question here MSDN Forums: WebBrowser Find Dialog
Hope that is exactly what you are looking for.
Just take input from the user in a textbox [here txtNoteSearch] and then follow the following code to implement the search. Following code demonstrates the search and highlight.
private void WebBrowser_DocumentCompleted(object sender, System.Windows.Forms.WebBrowserDocumentCompletedEventArgs e)
{
mshtml.IHTMLDocument2 doc2 = WebBrowser.Document.DomDocument;
string ReplacementTag = "<span style='background-color: rgb(255, 255, 0);'>";
StringBuilder strBuilder = new StringBuilder(doc2.body.outerHTML);
string HTMLString = strBuilder.ToString();
if (this.m_NoteType == ExtractionNoteType.SearchResult)
{
List<string> SearchWords = new List<string>();
SearchWords.AddRange(this.txtNoteSearch.Text.Trim.Split(" "));
foreach (string item in SearchWords)
{
int index = HTMLString.IndexOf(item, 0, StringComparison.InvariantCultureIgnoreCase);
// 'If index > 0 Then
while ((index > 0 && index < HTMLString.Length))
{
HTMLString = HTMLString.Insert(index, ReplacementTag);
HTMLString = HTMLString.Insert(index + item.Length + ReplacementTag.Length, "</span>");
index = HTMLString.IndexOf(item, index + item.Length + ReplacementTag.Length + 7, StringComparison.InvariantCultureIgnoreCase);
}
}
}
else
{
}
doc2.body.innerHTML = HTMLString;
}
I am a newbie in C# I just have a doubt.I have two group boxes,each of them has three radio buttons in it,If I want to select each radio button from each groupbox and write a condition for that ,,How can I do that. Below is the code:
public void SaveMyTextBoxContents()
{
string path = usbLetter +"MSREAD.txt";
if (lbItems.SelectedIndex == -1)
{
if (rdBtnMed.Checked)
{
using (StreamWriter File = new StreamWriter(filepath))
{
foreach (string item in lbItems.Items)
{
saveAllText = medium + " " + item;
outputFile.WriteLine(saveText);
}
}
}
}
else if (rdBtnMedium.Checked && rdBtnN.Checked)
{
using (StreamWriter File = new StreamWriter(filepath))
{
foreach (string item in lbItems.Items)
{
saveAllText = mediumNo + " " + item;
outputFile.WriteLine(saveText);
}
}
}
}
}
Please help me I got stuck up with this.
Thanks Krik
Make small panels to the size of radio button pairs and place those radio buttons on them (two each). E.g separate for male, female; separate for young, old etc. The panel won't show on run. This will work Insha'Allah in a group box too.
You're brackets are off, so it only checks rdBtnMedium and rdBtnN if lblItems.SelectedIndex != 1. Here's what I think you need:
if (lbItems.SelectedIndex == -1)
{
if (rdBtnMed.Checked)
{
using (StreamWriter File = new StreamWriter(filepath))
{
foreach (string item in lbItems.Items)
{
saveAllText = medium + " " + item;
outputFile.WriteLine(saveText);
}
}
}
else if (rdBtnMedium.Checked && rdBtnN.Checked)
{
using (StreamWriter File = new StreamWriter(filepath))
{
foreach (string item in lbItems.Items)
{
saveAllText = mediumNo + " " + item;
outputFile.WriteLine(saveText);
}
}
}
}