I have a Pocket PC Chat application where i need to open so many forms for private chat sessions. The problem I faced was that when I opened a few form I saw and instance in Task Manager. For 10 opened forms I saw 10 Instances. To work around on it I came to the solution that I have to have Text only on 1 Window of application at a time. So I wrote 2 classes:
1) A FormBase class from which all my forms are inherited:
public partial class BaseFormCommSuiteMobile : Form
{
private string uniqueID;
{
private string uniqueID;
public BaseFormCommSuiteMobile()
{
InitializeComponent();
this.uniqueID = Guid.NewGuid().ToString();
}
{
InitializeComponent();
this.uniqueID = Guid.NewGuid().ToString();
}
public string UniqueID
{
get { return this.uniqueID; }
}
{
get { return this.uniqueID; }
}
private void BaseFormCommSuiteMobile_Load(object sender, EventArgs e)
{
OpenedFormsCollection.AddForm(this);
}
{
OpenedFormsCollection.AddForm(this);
}
private void BaseFormCommSuiteMobile_Closing(object sender, CancelEventArgs e)
{
OpenedFormsCollection.CloseAll();
}
{
OpenedFormsCollection.CloseAll();
}
private void BaseFormCommSuiteMobile_Activated(object sender, EventArgs e)
{
this.Text = "XXXX Application";
OpenedFormsCollection.UpdateFormsText(this.uniqueID);
}
}
{
this.Text = "XXXX Application";
OpenedFormsCollection.UpdateFormsText(this.uniqueID);
}
}
The Helper class which Removes the Text from all Other Forms except the Active One!
public static class OpenedFormsCollection
{
private static Dictionary<string, BaseFormCommSuiteMobile> openedFormsDictionary = new Dictionary<string, BaseFormCommSuiteMobile>(10);
{
private static Dictionary<string, BaseFormCommSuiteMobile> openedFormsDictionary = new Dictionary<string, BaseFormCommSuiteMobile>(10);
public static void UpdateFormsText(string uniqueID)
{
Dictionary<string, BaseFormCommSuiteMobile>.ValueCollection openedForms = openedFormsDictionary.Values;
foreach (BaseFormCommSuiteMobile form in openedForms)
{
if(form.UniqueID != uniqueID)
{
form.Text = "";
}
}
}
{
Dictionary<string, BaseFormCommSuiteMobile>.ValueCollection openedForms = openedFormsDictionary.Values;
foreach (BaseFormCommSuiteMobile form in openedForms)
{
if(form.UniqueID != uniqueID)
{
form.Text = "";
}
}
}
public static void AddForm(BaseFormCommSuiteMobile formToBeAdded)
{
if(!openedFormsDictionary.ContainsKey(formToBeAdded.UniqueID))
{
openedFormsDictionary.Add(formToBeAdded.UniqueID,formToBeAdded);
}
}
{
if(!openedFormsDictionary.ContainsKey(formToBeAdded.UniqueID))
{
openedFormsDictionary.Add(formToBeAdded.UniqueID,formToBeAdded);
}
}
public static void RemoveForm(string uniqueID)
{
openedFormsDictionary.Remove(uniqueID);
}
{
openedFormsDictionary.Remove(uniqueID);
}
public static void CloseAll()
{
lock (openedFormsDictionary)
{
Dictionary<string, BaseFormCommSuiteMobile>.ValueCollection openedForms = openedFormsDictionary.Values;
BaseFormCommSuiteMobile[] forms = new BaseFormCommSuiteMobile[openedForms.Count];
int i = 0;
foreach (BaseFormCommSuiteMobile form in openedForms)
{
forms[i++] = form;
}
{
lock (openedFormsDictionary)
{
Dictionary<string, BaseFormCommSuiteMobile>.ValueCollection openedForms = openedFormsDictionary.Values;
BaseFormCommSuiteMobile[] forms = new BaseFormCommSuiteMobile[openedForms.Count];
int i = 0;
foreach (BaseFormCommSuiteMobile form in openedForms)
{
forms[i++] = form;
}
for (int loop = i - 1; loop >= 0; loop--)
{
forms[loop].Close();
}
}
}
}
{
forms[loop].Close();
}
}
}
}
Right! Now I have only one problem. How can I close all Forms when I close the Application from Task Manager. The CloseAll() function in the above class solves this problem but I have to set MinimizeBox property of all the Forms to true get it working. Otherwise If I close a form even not from Task Manager It'll close all other Forms.
I want to set MinimizeBox property of the main Form to true all other forms shuold have this proprty set to false. I want to know is there any way to to solve this problem or any way to detect that if this Form was closed from the Task Manager or from the Close Button.
Any help will be highly appreciated.
Best Regards,

So many Forms Issue Still not solved :(
Cian
Hello Sergey,
First of all, I thank you for reading this much large post and getting my point at the end. Really Appreciate it! You exactly understood what I need and want to do. You are right at what you are saying but the problem is I set text property of main form to = "dsafsafdsafdsa" Ok its fine what happens when a new Window comes over it I see The Title, because its empty and I can See "Start" there of Task Bar! I want that I can see name of my application on the title each form of my application even if some other form is hiding the main Form...
So, Any help, Any Solution
Thank you and Best Regards,
Ofir Epstein
Hello Mike,
I thank you from the bottom of my heart to reply my past, I got helpless literally that no body replied my post for about 2 weeks with a +ve Solution.
Yes, I first considered using TabControl but there is a problem, All my TabPage area is occupied by 2 TextBoxes as I mentioned its a chat application and I wanted to close TabPages through TabPage's Header not the Client area of TabPage but no luck, no one could help me in that too! Please see these posts:
http://forums.microsoft.com/MSDN/ShowPost.aspx PostID=780755&SiteID=1
http://forums.microsoft.com/MSDN/ShowPost.aspx PostID=777543&SiteID=1
I didnot prefer to use Panels and also did not give it a try because I was thinking that how I'll detect which Panel is UP Like I have 10 Panels for 10 Chat sessions, I wanted to know Z-Order!
Anyhow I think you have understood my problem why I need to know Z-Order (To make some menu Availble on one panel but not available when some other panel is on top etc).
Then I gave up this Idea and thought to use seperate Forms!
I know using Panels istead of seperate Forms will be more effiecient when switching and will require lesser memory to run! That is Great if your provide me any working example or give me some Idea how to do that, Also tell me what is Owned dialogs May be I need it some time in Future.
In case if you want to send me a sample application with code then my email addresses are:
rizwansharp [at] hotmail [dot] com
r [dot] ahmed [at] protectstar.com
In last thanks a lot for your great help and support, I respect it from my heart.
I'm looking forward for your reply/email!
Thank You So much!
Rizwan
Pwint
Please help me in solving this problem!
Best Regards,
zhihao
I’m not sure if I correctly understood your scenario but why don’t you have a title for the main form only (all chat session form will have the Text property set to “”) In this case, you don’t have to worry about setting the Text property for the currently active form and you can close only the main form from the Task manager.
Shahid Mahmood
Hi Rizwan, I can help you with this.
I read that you want to always have the title of your main application visible. Have you tried using panels (or a tab control) inside your main application instead of separate forms This would simplify your application somewhat and your main application title bar (caption) would always be visible. When I've done this in the past, I've used other controls like a comboBox or menus to allow the user to switch between the panels (BringToFront()).
Let me know if you need an example of this, or if there's other reasons why you require using separate forms. If you have to go the separate forms route, we should look into using a netcf v2 feature: "owned dialogs" which would prevent each form from being displayed in the task manager.
mike
icemart525
Anyone to help me in this situation
Please its very urgent! I want to solve it as soon as possible or somebody sugest me any good alternate
Best Regards,
Lil_AzZa
Hello Mike,
Great Solution, Highly appreciated! I have tested it works like a Charm. But for now I had already used TabControl with some good control on Closing tabs, that day I saw a sample on MSDN Tabbed Browser Control in Compact Framework, Which gave me good Idea to close and open the Tabs, I simple put a tool bar and put a close button to close the selected Tab!
Anyways, I really Appreciate your effort in providing me a good solution which I'll really use in my next Application
.
Thank You Soo Much Mick,
Best Regards,
Rizwan
,
AndrewVos
Here's some sample code that demonstrates how you can flip panels. This sample uses a comboBox to switch between panels. When the comboBox selected index changes, that's where you would tell what panel is on top. I would recommend putting additional code (change status bar text, etc..) in the SelectedIndexChanged() method.
I've pasted in the contents of 2 files where the first file is demo code that uses a PageFlipperControl. The PageFlipperControl code is in the second file, after the demo. I think this should get you going in the right direction, let me know.
mike
I forgot to check the box "contains code sample", so where you see an emoticon, it should read [ n ].
DEMO =======================================================
using System;
using System.Windows.Forms;
using System.Drawing;
public class Test : System.Windows.Forms.Form
{
Color[] Colors = new Color[]
{
Color.Red, Color.Blue, Color.Yellow, Color.Green, Color.Azure, Color.DarkGoldenrod
};
PageFlipperControl book;
protected override void OnLoad(EventArgs e)
{
this.Size = new Size (200, 300);
this.Text = "PageFlipperDemo";
book = new PageFlipperControl();
book.Parent = this;
book.Bounds = new Rectangle (0, 0, this.ClientSize.Width, this.ClientSize.Height);
Label label;
for (int n = 0; n < Colors.Length; n++)
{
Page page = book.AddPage("page:" + n);
page.Panel.BackColor = Colors [ n ];
label = new Label();
label.Text = "label:" + n;
label.Location = new Point(0, 0);
page.Add (label);
}
}
public static void Main(string[] args)
{
Application.Run(new Test());
}
}
PAGEFLIPPERCONTROL ================================================
using System;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Drawing;
public class PageFlipperControl : Control
{
const int COMBO_HEIGHT = 30;
ComboBox pages;
Page currentPage;
public PageFlipperControl() : base()
{
pages = new ComboBox();
pages.Parent = this;
pages.Text = "PageFlipper";
pages.SelectedIndexChanged += new EventHandler(this.pages_SelectedIndexChanged);
}
// resize the 2 components to fill the client area of this control
protected override void OnResize (EventArgs e)
{
if (this.pages != null)
this.pages.Bounds = new Rectangle (0, 0, this.ClientSize.Width, COMBO_HEIGHT);
if (this.currentPage != null)
this.currentPage.Panel.Bounds = new Rectangle (0,
this.pages.Size.Height,
this.ClientSize.Width,
this.ClientSize.Height - this.pages.Size.Height);
}
public Page AddPage (string name)
{
Page page = new Page (this, name);
return this.AddPage (page);
}
public Page AddPage (Page page)
{
pages.Items.Add (page);
page.Panel.Parent = this;
// if this is the first page, then make it's panel visible
if (pages.Items.Count == 1)
pages.SelectedIndex = 0;
return page;
}
public Page[] Pages
{
get
{
Page[] pageArray = new Page[pages.Items.Count];
for(int n = 0; n < pages.Items.Count; n++)
pageArray [ n ] = (Page)pages.Items [ n ];
return pageArray;
}
}
private void pages_SelectedIndexChanged(object o, EventArgs e)
{
Page page = (Page)this.pages.Items[this.pages.SelectedIndex];
SetCurrentPage (page);
}
void SetCurrentPage(Page page)
{
this.currentPage = page;
page.Panel.Bounds = new Rectangle (0,
this.pages.Size.Height,
this.pages.Size.Width,
this.ClientSize.Height - this.pages.Size.Height);
page.Panel.BringToFront();
}
}
public class Page
{
public string Name;
public Panel Panel;
public Page (Control parent, string name)
{
this.Name = name;
this.Panel = new Panel();
this.Panel.Text = name;
this.Panel.Parent = parent;
}
public Page (string name) : this (null, name)
{
}
public Control Add (Control c)
{
c.Parent = this.Panel;
return c;
}
public override string ToString()
{
return this.Name;
}
}