Get variables from list in another method? - c#

I'm writing a webcam app and I need to write and read about 15 variables. I have two forms, the main window and the options window. When I save my options I do something like this:
string[] lines = {x , y, ..., z };
System.IO.File.WriteAllLines(#"config.cfg", lines);
In my main window I read the variables using the StreamReader function:
public void Foo()
{
List<string> lines = new List<string>();
while (!reader.EndOfStream)
{
lines.Add(reader.ReadLine());
reader.Close();
}
x = Convert.ToInt32(lines[0]);
y = Covert.ToString(lines[1]);
// and so on...
}
The problem is I don't know how to access x and y in another method. Btw: I declared all my variables as public static. Can anyone please help?
Edit
It is a windows forms app, the two windows do not exist at the same time. Maybe someone can give me a hint how to store those variables using a different method? The only thing I know I could do is store the vars using a MySQL database, but doesn't make much sense.
I'll try to clarify: what I would like to do, is pass x and y from the method Foo to another method. I can't use global variables, because reading the variables from the file requires a method.

use properties=> setting to save your values if you will need it the next time.
it's simple and help you to avoid some problems

Do both forms exist at the same time? i.e in skype you have your main skype window and your chat windows?
If so just make a CameraUpdated event, which sends the lines changed to any subscribers, then that way you can just get your main window to bind to any new child windows events, so it will be notified.
To do this you would need to make a custom event arg to pass the data, a delegate for the event name and args, and expose the actual event on your form.
If however only one form exists at a time, you could either have an in memory store you push data to and then read it out of (much like your current implementation), or when you flip from one form to the other you pass in the data that has changed.
Ultimately I would try to avoid having global style data, be it in a file, memory or a global program variable, and opt for some loosely coupled approach, but without knowing your actual implementation its difficult to advise a specific solution.

Class members that are declared as public static are accessible with:
ClassName.MemberName

Related

how "intercept" messagebox & modify its content, and back to normal flow?

I have a bunch of messageboxes in an existing app, both simple informations to user and also questions.
I would like to "intercept" them (for sure not the correct IT wording), change automatically its content, and then normally display it to user.
The "OK" or other standard return should be returned/forwarded to the initial messagebox.
The modification function is a kind of translation, but for the purpose of demonstration, lets say that this special function does += " AAA" to the content and += " BBB" to the top header.
Note1: while searching, I have seen several custom message boxes, but
these are additional controls, mainly for changing the button captions
or style, not to "intercept". Please correct.
Note2: fully agree that a better & cleaner MVVM structure would have avoided the
trick needed above, but this big app started some time ago, with a
very small and different aim
As far as I know this isn't possible. You cannot have a reference to a MessageBox, so you cannot access it in any way once it is open.
According to the documentation:
You cannot create a new instance of the MessageBox class. To display a message box, call the static method MessageBox.Show.
This means that you cannot do like the following:
var box = new MessageBox([stuff]);
MS deliberately made the constructor or constructors of that class private (or protected), to make you use the factory method instead (MessageBox.Show();). Note that since they are explicitly defined, just not accessible, this means that no implicit constructor is generated either.
Doing this also won't work:
var box = MessageBox.Show([stuff]);
The Show method doesn't return a reference to the open box itself, but to the DialogResult object after it closes.
As for your situation, the only ways I can think of to solve your problem would be to either go through the program and change the strings, or create a new custom control and ditch the MessageBox entirely. You may be able to find another way, however "intercepting" the MessageBox instances isn't possible.
Assuming that the code uses System.Windows.MessageBox.Show calls using text and caption arguments, you can try defining a public static MessageBox class in a common namespace of your application providing a similar Show method that updates the arguments and calls the original MessageBox.Show method, e.g.:
public static class MessageBox
{
public static void Show(string text, string caption)
{
text += "AAA";
caption += "BBB";
System.Windows.MessageBox.Show(text, caption);
}
}
Note: this will only work if you are able to rebuild the solution from source code, as it requires adding a new source code file (the custom MessageBox class), and then rebuilding the solution.

C# Write to a RichTextBox in a Form from different classes

I am using a RichTextBox which is in a Form that I am basically using as a log window whilst the program performs various functions - much like a debug window. Various methods write to the window as they perform tasks on various files. The simple class looks like this:
public partial class ValidationWindow : Form
{
public ValidationWindow()
{
InitializeComponent();
}
public void writeToWindow(string text)
{
if (richTextBoxValidationWindow.TextLength > 0)
{
richTextBoxValidationWindow.AppendText(Environment.NewLine + text);
}
else
{
richTextBoxValidationWindow.Text = text;
}
}
}
I have instantiated the Form containing the textbox from a class in the usual fashion i.e ValidationWindow valWindow = new ValidationWindow(), then call the show() method to display the window, and i can then write to it using the method in the above class called writeToWindow. All good.
I now need to be able to continue to write to the same window from other classes. I obviously don't want to create more instances of the same Validation Window. So what is the best way to do this please?
It sounds like you need access to this form from other forms and classes. In other words, you need this form to be globally accessible.
The simplest way to do this is add a global variable to your application, and save a reference to the logging window in that variable. Then, if any other class needs to log, it can access the logging window via the global variable.
However, this is perhaps not the best way to do this, as you are tying your logging to that window. What happens if you decide to log a different way? You'd have to change every reference to the window, which means changes all over the application. You would be better off looking at something like messages, which allow the calling code to send out a message requesting that something be logged, but not needing to know anything about the class that receives the message and does the actual logging. I know WOF supports this with MVVM, but am not sure how you would do it in WinForms (assuming that's what you're using). Maybe do a search on "winforms messages" and see what comes up.
Hope that helps

How to get inside private static Tuple, and use numericUpDown to change Math.Round

this is my part of code to parse a NMEA data (source here Plot chart using values from richTextBox C#) . This function get back latitude from richTextBox, and convert it to decimal notation. I need it, to plot charateristic from 4 another GPS module (to compare accuracy all four GPS).
This is my problem. I want to use a "numericUpDown" to change Math.Round (below I have value - 11). I cant get inside Tuple because I have error (I tried to do something, but it didnt work). Can anybody know, what should I do?
private static Tuple<double>[] szerokosc(string[] lines)
{
return Array.ConvertAll(lines, line =>
{
string[] elems = line.Split(',');
double we = 0.01 * double.Parse(elems[3], EnglishCulture);
int stopnie = (int)we;
double minuty = ((we - stopnie) * 100) / 60;
double szerokosc_dziesietna = stopnie + minuty;
return new Tuple<double>(Math.Round(szerokosc_dziesietna, 11));
});
;
}
I want something like this:
return new Tuple<double>(Math.Round(szerokosc_dziesietna, round_value));
where (for example):
int round_value = (int)numericUpDown1.Value;
and I declare:
numericUpDown1.Minimum = 1;
numericUpDown1.Maximum = 11;
Please help :).
As you figured out, and as I suspected but couldn't be sure as I didn't have all the code, the problem was caused by the static keyword in your method. Removing it fixed the problem.
The static modifier is used to indicate that the method/property/field/etc. belongs to the class, rather than to instances of the class. Inside a static method or property, you cannot use this to refer to the 'current' instance of the class, as static methods don't have a current instance.
In Windows Forms, the fields created for the various controls in the forms, such as your numericUpDown2, are always 'instance' fields, i.e. not static, so they belong to each individual instance of the form, rather than to the Form1 class. That way, if you have two different Form1s open at the same time, the corresponding controls in the two forms can have different values. (You might only need to use one Form1 in your application, but other forms in other applications may need to be used more than once.) A static method in the Form1 class cannot see any of these controls because it belongs to the Form1 class, where an instance (i.e. non-static) method belongs to each individual form. So a static method cannot see the controls because it can't know which form of possibly many the controls are in.
As you are a beginner, the advice I would give to you if you are unsure about whether you need to make a method static would be not to make the method static. If a method makes no use of any instance-specific fields or methods, you can try making it static if you wish, and see if doing so introduces any compiler warnings.

Use of static class in C#

I'm developing an appliaction that has 2 forms and I ran into a problem. When I create a new instance of a class in Form2, then close Form2, I lose the instance values. So, I've solved this using static class, is this the correct approach?
The class name is Matriz_de_registracion and I have a function within it that's called "solver" that assigns values to the class properties ("Double MR0" is one of the variables as an example)
here's the code in Form2 (see I don't use the "new" statement otherwise once I close form2 I loose the instance values..
private void btn_iniciar_registro_de_puntos_Click(object sender, EventArgs e)
{
Matriz_de_Registracion.solver(_pois);
}
Then I can reference, in Form1, one of the properties of the Class by just doing this:
Matriz_de_Registracion.MR0
Now, is this correct approach or static classes are used for something else? I just wan to reference the values of the MR0 variable across all my forms without having to pass the instances through forms every time I open/close forms.
This is not the right approach. You should copy the values from the form object after it has closed but before you get rid of it.
The problem with using static data anything other than extremely sparingly is that you will find it makes the application much harder to work on as it gets larger - for example, you wouldn't be able to open two instances of the form at the same time, as they'd tread on each other's data.

SelectedIndexChange event not firing when using through reflection

I have a windows form with a listview control. I have a selectedIndex changed event where i am performing some action. Through reflection I am trying to set the value of the list view.
But the event is not getting fired. Any help will be helpfull.
Edit
The event looks like
private void LV1_SelectedIndexChanged(object sender, EventArgs e)
{
if (LV1.SelectedItems.Count>0)
{
if (LV1.SelectedItems[0].Text.ToString() == "testing")
{
// Do some work.
}
}
}
I am using relection in another project and changing the selected item as follows
Assembly a = Assembly.LoadFrom(exePath);
Type formType = a.GetType(formName);
testForm = (Form)a.CreateInstance(formType.FullName);
if (testForm != null)
{
Type t1 = testForm.GetType();
FieldInfo fi = t1.GetField(controlName, flags);
object ctrl = fi.GetValue(testForm);
ListView l1 = (ListView)ctrl;
l1.Items[0].Selected = true;
}
Automating another application is fun howver not a trivial task. There's a few options but I guess most of them is out of scope for you. One would be to programatically take over the mouse and keyboard and trough those channels manage the program. Another way would be to manipulate memory, As I said neither are trivial to implement and very easily broken if the aplpication is updated.
I would suggest instead of trying to automate the application to look for infliction points. Are there any service endpoints you could automate and achieve the same result? any API or dll's used by the application you could use instead?
If you really have to automate the application there do exist several frameworks for doing that (usually build for testing purposes). The only one I can think off right now is made by Assima as is ment for training purposes.
I think your problem is here:
testForm = (Form)a.CreateInstance(formType.FullName);
You are creating a new instance of the form. I'm assuming your main project is an exe that runs an shows the form. Your second project is then another exe that runs and wants to change the selected item. By creating a new instance of the form you will be changing the selected item on the new form, not the old one.
What you need to do is somehow pass the form object over to the secondary project. possibly some static method that gets a singleton instance of the form maybe.
I'm still not entirely sure why you are using reflection, you could just give the second project a reference to the first.
The first question I'd ask is: why are you using reflection here? Just set the value through the public API. If you are messing underneath the public API, then yes: it is entirely possible that some events won't get fired.
Perhaps if you could show us exactly how you are doing this?

Categories

Resources