Categories
C#.NET Concept/algorithm Programming VB.NET/VB

MDI Window: C# way

So how can we make MDI Parent and Child Window in C#. The answer I found was that there is nothing inbuilt for it. So, I have two choice, either I modify the Window class and add MDI [Multiple Document Interface] coding in them or I found a alternative interface. 

It took less than 5 minute to decide that I can go with alternative interface after googling, the interface is TAB. Yup, much like your browser, they use TABs too, we create tab in  web portal, browser and lot of other things. So, they are perfect replacement for MDI window needs. The logic is as simple as, 

1. Create a TabControl on Main window.

2. Add couple of function, that search for TabItem in Tabcontrol if they exists or not, if exists focus them or add a new Tab Dynamically. Same logic on deletion of tab.

3. Create User Control from your Common custom Interface class and default UserControl object. Add these user control on Tab content when adding new tab.

I again didn’t keep the URL, but there is good example on it is available on MSDN and few other tutorial site. I try to post main component of logic below

namespace MyCommonLibrary
{
    /// 
    /// Deletgate for Tab Closing
    /// 
    /// 
    /// 
    public delegate void CloseTab(ITabbedWindow sender, EventArgs e);

    /// 
    /// Delegate to reload Tab Data.
    /// 
    /// 
    /// 
    public delegate void ReloadTabData(ITabbedWindow sender, EventArgs e);

    /// 
    /// Interface for Tabbed Windows Style MDI.
    /// 
    public interface ITabbedWindow
    {
        /// 
        /// Event for Closing Tab handle
        /// 
        event CloseTab CloseInitiated;

        /// 
        /// Event to reload Tab Data
        /// 
        event ReloadTabData Reload;

        /// 
        /// Name of the Tab Window
        /// 
        string TabName { get; set; }

        /// 
        /// Title of the Tab Window
        /// 
        string TabTitle { get; set; }

        /// 
        /// If Tab is loaded fully.
        /// 
        bool IsAllowRefresh { get; set; }


        void ReloadData();
    }
}

Above one is my common Interface which I use to implement in my User Control. After this all I have to do is add below function in my Parent window which has TabControl added to it.

#region Tab Functions
 #region Tab Functions

        public void AddChildWindow(ITabbedWindow childWndow)
        {
            if (childWindows.ContainsKey(childWndow.TabName))
            {
                foreach (TabItem tabItem in MDIContainer.Items)
                {
                    if (tabItem.Name == childWndow.TabName)
                    {                        
                        tabItem.Focus();
                        if (childWndow.IsAllowRefresh)
                        {
                            childWndow.CloseInitiated += new CloseTab(childWndow_CloseInitiated);
                            tabItem.Content = childWndow;
                        }
                        ITabbedWindow uc = tabItem.Content as ITabbedWindow;
                        try
                        {
                            if (uc != null )
                            {
                                uc.ReloadData();
                            }
                        }
                        catch { }
                        break;
                    }
                }
            }
            else
            {
                TabItem tabItem = new TabItem();
                tabItem.Name = childWndow.TabName;
                tabItem.Header = childWndow.TabTitle;
                tabItem.Content = childWndow;

                childWndow.CloseInitiated += new CloseTab(childWndow_CloseInitiated);

                MDIContainer.Items.Add(tabItem);
                MDIContainer.SelectedItem = tabItem;
                ITabbedWindow uc = tabItem.Content as ITabbedWindow;
                try
                {
                    if (uc != null)
                    {
                        uc.ReloadData();
                    }
                }
                catch { }
                
                childWindows.Add(childWndow.TabName, childWndow.TabTitle);
            }
        }

        public void RefreshTabContent(string mTabName)
        {
            foreach (TabItem tabItem in MDIContainer.Items)
            {
                if (tabItem.Name == mTabName)
                {
                    tabItem.Focus();
                    ITabbedWindow uc = tabItem.Content as ITabbedWindow;
                    try
                    {
                        if (uc != null)
                        {
                            uc.ReloadData();
                        }
                    }
                    catch { }
                    break;
                }
            }
        }

        void childWndow_CloseInitiated(ITabbedWindow sender, EventArgs e)
        {
            foreach (TabItem tabItem in MDIContainer.Items)
            {
                if (tabItem.Name == sender.TabName)
                {
                    MDIContainer.Items.Remove(tabItem);
                    childWindows.Remove(sender.TabName);
                    break;
                }
            }
        }
        #endregion

I just paste the portion where I control Tab, but it goes to code behind of mainwindow.xaml. One thing to note here is I use a SortedDictionary object to store the name of Tab in it for searching and retrieval of it. Rest is clear I guess.