Why I lose the variable value when doing form.ShowDialog()? - c#

See this:
MAIN FORM CODE:
public partial class Principal : Form
{
string directoriodelarchivo;
...
....
private void opendicomdir_Click(object sender, EventArgs e)
{
directoriodelarchivo = System.IO.Path.GetDirectoryName(ofd.FileName);
var form = new dicomdirselectionform(_reader);
form.ShowDialog();
}
}
I do some stuff in the other form and then press a button to return to the main form, thing is that when I returin to the main form, the variable "directoriodelarchivo" IS EMPTY!
Why that is? I'm new to C# and I'm trying to figure out if there's something I'm missing

It's not immediately clear to me what may be causing this. To try to find the reason, I would suggest doing something like this:
Remove all other code that may be altering directoriodelarchivo.
Add some easy way to check the value of directoriodelarchivo after every step in your code. (Example: https://ideone.com/E38zc2)
If this works, try finding the code that you removed in step 1 that's breaking your application by changing directoriodelarchivo. If it doesn't, ofd.FileName might be causing an unsatisfactory value for directoriodelarchivo.

There are 2 causes for that
You re-create this form somehow. So it has value by default.
You change that var in some code. Just try to find references for that var and you will make sure it.
I hope it will help you!

Related

Assign values to the variables one time after the operation for the first time

If I need To Make Variables that take value by user at the first run and keep this value when the application restarted and be able to change it any time we need that
How can I do that in C# public Class??
Keeping the value, even if the application is restarted can be referred to as 'keeping state'. If you want the application variables to keep state, even through a restart, you will have to store them somewhere else (a database perhaps) and have some logic to then read from the database when the app starts.
Your question is quite generic but if you provided code examples you may get a more detailed answer.
a Class may not be needed for it will be just another class which is rather not needed to be implemented.
Use a form instead (based on your tag, WinForm)
Let this be the form used for this solution
Open solution explorer and double click Properties. Upon opening the Application Properties, click Settings on the left side and make a variable as shown on picture below
Set the form to auto close if the boolean settings is set to true and do the other way around if not. Then you must set the btnSubmit to make the bool setting true upon clicking. Let your application concept's code be as follows. (See picture below)
(IF YOU CAN'T SEE THE CODE IN THE PICTURE DUE TO RECEIVING CAN'T HANDLE REQUEST FROM IMGUR, the following codes are what the last picture contains)
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
if (Properties.Settings.Default.launchedFirstTime == true)
{
Close();
}
}
private void btnSubmit_Click(object sender, EventArgs e)
{
Properties.Settings.Default.firstTimeString = txtFirstTimeString.Text;
Properties.Settings.Default.launchedFirstTime = true;
Close();
}
}
}
EDIT:
HERE IS THE DEBUGGING OF THE APPLICATION. IT DOES SET VALUES
(See firstTimeString and launchedFirstTime in the LOCALS, found at the lower left of the picture)
you can use xml or txt files to write these values and amend when you need. its just a work around.
Thanks

Can't add strings to listbox

Hi i'm trying to collect output of this library into listbox.
Here's part of code from the test project, with i've tried to modify:
public partial class Form1 : Form
{
D.Net.Clipboard.ClipboardManager Manager;
public Form1()
{
InitializeComponent();
Manager = new D.Net.Clipboard.ClipboardManager(this);
Manager.Type = D.Net.Clipboard.ClipboardManager.CheckType.Text;
Manager.OnNewTextFound += (sender, eventArg) =>
{
button1.Text = eventArg; //just testing, working correctly
listBox1.Items.Add(eventArg); //does not show neither result nor any error
MessageBox.Show(String.Format("New text found in clipboard : {0}", eventArg));
};
}
private void button1_Click(object sender, EventArgs e)
{
listBox1.Items.Add("test"); //working correctly
}
}
Problem is when i trying to add item into the list it does nothing, and further lines of code (in this function) don't run at all.
I tried to fix it thru some custom classes and different expressions but nothing worked for me (yes, I'm a noob). Also tried to do it with textBox, result is the same, but text on buttons changes as it should.
Looks like completely lame problem, but i've spent almost 5 hours by googling, reading microsoft documentation, SO, and closest i can get is this as i can see stuff suggested there already implemented.
The OnNewTextFound event is firing on a separate thread from the UI, so your attempt to update the UI is failing. An exception is thrown in the other thread, aborting the rest of that method, but your UI thread keeps executing.
You'll have to call Invoke() in order to execute the code back on the UI thread:
listBox1.Invoke(new MethodInvoker(delegate { listBox1.Items.Add(eventArg); }));
You are adding EventArgs to the Items list for the ListBox. Is there an eventArgs.[someString] that you can add?
You cannot add items to a listbox during the construction of the form. You need to move the code into the Load event.

Lazy Instantiation of UserControl

I have a WPF application that I am trying to switch the contents of a window efficiently. I have come up with the solution of the following:
App.cs
internal static Lazy<HomeUserControl> HomePage;
MainWindow.cs
public MainWindow()
{
InitializeComponent();
Application.Current.MainWindow.Content = App.HomePage;
}
HomeUserControl.cs
public HomeUserControl()
{
InitializeComponent();
}
I am running into a problem that MainWindow.Content is basically being set to a blank window (it is actually changing the content of MainWindow). If I use App.MainWindow.Content = new HomePageUserControl(), everything works as it should. However, I would like to keep one instance of the page, which is why I made a static one in the App class. This problem occurs whether Lazy<> is used or not. I have tried a check to see if HomePage was null, and I got back a label that said Value is not created., which I'm pretty sure is the representation of an uninitialized Lazy<>; however, this only occurs if I check App.HomePage == null. Any ideas?
Try
Application.Current.MainWindow.Content = App.HomePage.Value;

Custom User Control Not Initialized in Auto-Generated Code

This has happened many times before, but I never bothered to figure out why, and now I am tired of it:
For instance, I derive a class from RichTextBox or Panel, I rebuild my project to have the class added to the VS designer toolbox, and then I drag & drop the custom user control to a Form. Everything works fine, and I can run my project...
The problem comes when I edit properties of the Form or the custom user control through the designer. Sometimes, the designer removes the initialization line from its code-behind, causing an exception in the designer and the executable because the control remains uninitialized.
In other words, the following line is removed from say, Form1.Designer.cs:
this.customRichTextBox1=new CustomRichTextBox();
No other line is removed from the code-behind, so the attributes of the custom control are still set, although the variable stays uninitialized.
My solution has always been to manually initialize my user control in the designer code-behind, but the designer eventually removes it again.
I believe that this does not happen when I build a Custom UserControl through the designer (but I am not completely sure of this). It only happens when I define something like the following manually:
class CustomRichTextBox:RichTextBox{}
This is so annoying. What am I doing wrong?
As #Cody requested, here are the steps to reproduce the problem. I am using VS2010, but I've had this problem since 2005, I think.
Step 1. Create new Windows Forms Application, any Framework
Step 2. Add the following class below your main Form class: (It just happens that this is the control that is causing me this problem this time.)
class CustomRichTextBox : RichTextBox
{
Timer tt = new Timer();
internal CustomRichTextBox()
{
tt.Tick += new EventHandler(tt_Tick);
tt.Interval = 200;
}
protected override void OnTextChanged(EventArgs e)
{
tt.Stop();
tt.Start();
}
void tt_Tick(object sender, EventArgs e)
{
System.Diagnostics.Trace.WriteLine("Hello world!");
}
}
Step 3. Press F6 to rebuild.
Step 4. Add the CustomRichTextBox control to your Form by dragging and dropping from the Toolbox.
Step 5. If you wish, you may press F5 to test the application, but it should work. Close the running application.
Step 6. Press F6 to rebuild, and at this point, the designer should crash with the following message: "The variable 'customRichTextBox1' is either undeclared or was never assigned." (In one case, the whole VS completely crashed, but the error is usually contained within the designer.)
Step 7. To correct the issue, go into the code-behind and initialize the variable, but next time you rebuild, the initialization line will be gone.
Thanks to everyone who tried answering my question and who posted comments that helped me diagnose and solve the problem.
The problem occurs when using an "internal" keyword with the control's constructor. Changing it to "public" fixes the problem. The reason for this behavior might be that the Designer's own classes cannot see the constructor because they are not within the namespace of my class unless it is marked public. This all makes sense, and I will use the public keyword from now on.
The class does not need to be in its own individual file or be the first declared class in the file as other answers suggested.
The following class works well because the constructor's keyword was changed to public.
class CustomRichTextBox : RichTextBox
{
Timer tt = new Timer();
public CustomRichTextBox()
{
tt.Tick += new EventHandler(tt_Tick);
tt.Interval = 200;
}
protected override void OnTextChanged(EventArgs e)
{
tt.Stop();
tt.Start();
}
void tt_Tick(object sender, EventArgs e)
{
System.Diagnostics.Trace.WriteLine("Hello world!");
}
}
Is your build set to Debug or it is Release?
I suppose that it is release as I think compiler optimizes the code and remove designer generated line.
Have you tried putting the control code in its own file? I've had problems even with the form designer in the past when the designer code was not int he first class in the file.
I had a similar problem that this posted helped me solve. I have a CustomControl that extends ComboBox, that class contained an internal private class YearItem. I've tried to highlight only the code needed to understand the problem and the solution.
public class YearsCbo : ComboBox //Inherits ComboBox
{
public YearsCbo() {
fill();
}
private void fill() { // <<<=== THIS METHOD ADDED ITEMS TO THE COMBOBOX
for(int idx = 0; idx < 25; idx++) {
this.Items.Add(new YearItem());
}
}
// Other code not shown
private class YearItem {} // <<<=== The VS designer can't access this class and yet
// it generated code to try to do so. That code then fails to compile.
// The compiler error rightfully says it is unable to access
// the private class YearItem
}
I could drag/drop that control YearsCbo onto a form and it worked correctly, but after I returned and edited the form the VS designer generated code that would not compile. The offending code something like this:
Dim YearItem1 As my.ns.YearsCbo.YearItem = New my.ns.YearsCbo.YearItem()
Dim YearItem2 As my.ns.YearsCbo.YearItem = New my.ns.YearsCbo.YearItem()
// This was repeated 25 times because in my constructor I created 25 of these
Me.YearsCbo1.Items.AddRange(New Object() {YearItem1, 2, 3, ..., YearItem25 });
Notice that the designer generated code which tried to access the private class. It didn't need to do that but for some reason it did.
Through trial and error, and this post: How to tell if .NET code is being run by Visual Studio designer came up with a solution:
I added a property to tell if I am running in the designer.
public bool HostedDesignMode
{
get
{
if (System.ComponentModel.LicenseManager.UsageMode == System.ComponentModel.LicenseUsageMode.Designtime)
return true;
else
return false;
}
}
I also changed the constructor so that it doesn't call fill() so when the designer runs, there are no items in the ComboBox so the designer doesn't feel the need to manually create those items.
The "fixed" code is shown below:
public class YearsCbo : ComboBox //Inherits ComboBox
{
public YearsCbo() {
if ( ! HostedDesignMode ) {
fill();
}
}
private class YearItem {} // <<<=== Now the VS Designer does not try to access this
}
This code was written using VS2012 Premium on Win7x64 OS (in case it matters).

Instantiate a form, then find it later, without showing it initially

I am having a problem that is strange to me but hopefully is not so strange to someone else. : ) Some background: I am working on a simple IM client that allows the user to broadcast messages to multiple recipients. The goal is to create a chat form for each of the recipients containing the text of the broadcast message, then show that form only if the recipient responds to the broadcast-er. However, when the application receives a response then attempts to locate the form for that particular chat session (using Application.OpenForms) it cannot find it UNLESS I .Show at the time it is created. I would like to avoid having to show this form when it is created because this means that the user will see a flash on the screen. The form doesn't seem to really be created until I show it, but it would seem there has to be a way to do this without showing first. Can anyone assist?
I can provide code snippets if needed, I didn't in this post because this feels more like a conceptual misunderstanding on my part than a bug in the code. Thanks in advance!
Instead of using the form as a base class, do it the other way, create a class that can reference a form. That way, you'll keep the class informed of the content, and reflect it on the form (if it's initialized), not the other way around.
You shouldn't rely on Forms as a basis of your objects. Using Application.OpenForms should be unnecessary.
public class Contact
{
string displayname = String.Empty;
List<Message> history = new List<Message>();
MessageForm theform = new MessageForm(this);
public void OnEvent(Message msg)
{
if(msg.Sender != me && !theform.Visible)
theform.Show();
}
public void Tell(string message)
{
}
}
etc
Keep your contacts in some sort of list, and things should be relatively simple.
(Be aware that windows forms aren't thread-safe, and will throw an exception if you try to alter any properties of any of the controls from a different thread than main)
windows form has methods like Hide(),Show() and Activate(). use these method for your problem.
Why not store a reference to the form with the chat session and use that to call .Show() when you need to display the form:
session.form.Show();
You can then create the form without showing it and you don't have the overhead of calling Application.OpenForms each time you want to reference it.
I know this is stating the obvious but OpenForms won't find a form that hasn't been shown because it's not open.
As the form handle does not get created until the form is shown you can assign it manually like so:
mf = new MainForm();
/* Need to assign a handle to MainForm instance manually
as handle does not get created until form is shown */
IntPtr handle = mf.Handle;

Categories

Resources