My C#.NET Windows application dynamically creates a bunch of forms with no name and no borders, this works fine, however I later need to find these forms and set them to be the top most forms. My current logic is to write the myForm.Handle to a string at the time of creation so I can refer to that handle later.
And this is where it fails, when I'm ready to set it to be the top most windows, I do this:
Form myForm = Form.FromHandle(sFormHandle);
if (myForm != null) { myForm.TopMost = true; }
The sFormHandle is a string and it expects a IntPtr, how can I convert it, or do this in some other way?
Many thanks.
The Handle property on a form is an IntPtr.
Why have you stored it as a string?
The solution here is to store the handle as an IntPtr, not a string.
Better than that, if this is all .net windows forms code, why not keep a reference to the form rather than the handle?
Edit: added emphasis. Consensus from community seems to be that references to the forms should be retained and the handles should not be relied upon.
Form fr = (Form)Form.FromHandle(new IntPtr(int.Parse("0")));
and beware of direct refrence to a class...
you better try WeakRefrence because of COM class models
if you use a direct refrence to a class,
the class will not unload till all the refrences are removed!
Related
I wrote a C# app in Winforms and am now rewriting it in WPF. In the Winforms version I used the following to open another window while sending it information and receive information back from it:
using (showSelection showSelection1 = new showSelection(listBox2.SelectedItem.ToString()))
{
showSelection1.ShowDialog();
storage1.showID = showSelection1.showID;
storage1.numOfSeasons = showSelection1.numOfSeasons;
}
This worked fine, I sent the selected item from listBox2 and received showID and numOfSeasons using this code in the showSelection form:
this.showID = Convert.ToInt32(dataGridView1[2, dataGridView1.CurrentCell.RowIndex].Value);
this.numOfSeasons = dataGridView1[1, dataGridView1.CurrentCell.RowIndex].Value.ToString();
this.Close();
Now, in the WPF version I try the same thing:
using (ShowSelection showSelection = new ShowSelection(showListBox.SelectedItem.ToString()))
{
}
But inside the using( ) I get this error:
ShowSelection: type used in a using statement must be implicitly convertible to 'System.IDisposable'
I'm not really sure where to do from here. Can I fix this and still go about it the same way or is there a different way I should be doing this? The ShowSelection window is just a datagrid with a single button.
WPF components don't use Win32 handles (Window does, but it self-manages), so they have no need to be IDisposable, and you have no need to Dispose them or use them in a using block.
Once there are no more references to your Window it'll be marked for collection by the GC, same as other pure NET components.
In case you want to use it within a using block, you can implement IDisposable on your window manually, but it's indeed not needed.
In case you want to manually remove resources (and keep using it in a using block), then the simplest you can do:
public class ShowSelection : Window, IDisposable
{
public void Dispose()
{
/* here you'd remove any references you don't need */
}
}
But unless there's a need for it, I'd advise against doing so
it's simply says that ShowSelection class do not derive from IDisposable
so use it without the using:
ShowSelection showSelection = new ShowSelection(showListBox.SelectedItem.ToString());
and than access the properties you need to:
showSelection.#####
I am writing a program in C# for a Windows CE device and would like the application to be translated according to a language setting in the application itself.
I have already read some articles about localisation using resource files and translating forms using the 'Localizable' and 'Language' properties. From what I have read I understand that this type of form translation works with the OS language setting (correct me if I am wrong).
Now I am looking for a way to do the form translation dependent on my own in-program language setting, preferably using resource files.
I have already thought of doing this translation in the Load event of each form but maybe there are other solutions or best-practice for this. Any help is appreciated.
If you use the Language.resx, Language.[language]-[country].resx way of localizing, the generated class Language will have a property named Culture that can be set to override the current system culture.
Language.Culture = new CultureInfo("sv-SE");
label1.Text = Language.my_language_string;
If you want to use the ResourceManager-class it has a member GetResourceSet() that takes a parameter CultureInfo. I haven't tried to use GetResourceSet myself but it sounds like something you could use.
ResourceManager CultureResourceManager = new ResourceManager("My.Language.Assembly", System.Reflection.Assembly.GetExecutingAssembly());
ResourceSet resourceSet = CultureResourceManager.GetResourceSet("sv-SE", true, true);
resourceSet.GetString("my_language_resource");
MSDN-link:
http://msdn.microsoft.com/en-us/library/system.resources.resourcemanager.getresourceset(v=vs.80).aspxo
If you are going to put it in the Load event, consider making a template form. Somewhere in the template form, add your localisation checks. Then, have your other forms inherit the template, and they will get the Load event by default.
Learning C#:
I have structure of
form1 (splitcontainer)
userformLeft (button + sub-panel)
userformDisplay (loaded into panel in userformLeft)
userformRight
I want to execute a method in userformDisplay from form1 (timer in form1).
And the other way around, let's say I have public property form1.mainTimer, can
I call it from userFormDisplay like
myLong = this.parent.parent.mainTimer;
or similar.
yes.. you can do this:
myLong = ((form1)this.parent.parent).mainTimer;
Similar problems of communicating between one form and another... whether attaching to "events" of one, or calling / setting values to/from each other. Here are a couple links to questions I've answered to in the past that may help understand the relationships to do so.
Sample 1 with explicit steps to create two forms communicating back/forth to each other
Sample 2 somewhat similar, but attaching to events between forms
I have created an instance of a window inside a class, but I am unable to access the instance of the window from my other class directly.
Is there a way to reference the window instance I have already created using a C# method, perhaps searching through the open app windows until it finds the Dashboard window I am trying to access?
Application.Current.Windows gives you all windows, shouldn't be hard to find using its type.
(As Ed pointed out this does not sound like very good design, so you might want to think about how you can get things done without messy window references)
System.Reflection.Assembly assemby = System.Reflection.Assembly.GetExecutingAssembly();
System.Type[] types = assemby.GetTypes();
var varWindows = types.ToList()
.Where(current => current.BaseType == typeof(Window));
MessageBox.Show(varWindows.Count().ToString());
Application.Current.Windows gets us all instantiated windows, but the above code get us all windows.
How can I update and get values in a Windows Forms application while moving one form to other form (like cookies)?
I need to update the values to some variable and again I am going to refer stored values and need to do some calculations.
I have used cookies in ASP.NET but I am not able to find out the same concept in .NET Windows Forms (C#).
How can these issues be resolves?
You can use object references.
You can decalre a read/write Property for each variable you want to be available in another form and the use them for sharing your data.
One way to do this is to declare variables to be public, either in a global module or in any form.
public x as double
If it is declared in a module, you can access it with the variable name only. To access data declared in another form, use that form name with the variable: form1.x = 7
Another way is to declare a property in a form or other class.
A really simple way of getting cookie-like functionality would be to declare a static string dictionary in Program (Program.cs)
public static System.Collections.Specialized.StringDictionary SortOfLikeCookies = new System.Collections.Specialized.StringDictionary(); and read/write string values using Program.SortOfLikeCookies["Name"] = "Value";