Results 1 to 7 of 7

Thread: [RESOLVED] Pass control of another form to void ?

  1. #1

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2016
    Location
    Slovenia
    Posts
    575

    Resolved [RESOLVED] Pass control of another form to void ?

    Hi,

    In my Form2 I have to call a void inside button_click, and this void needs to pass a control which is on another form (Form1). How can I acces this control in C# ? Not some property, but a control Itself.

    I would prefer easiest way to do this, something like "Form1.Listview" in VB.NET.

    my void:

    Code:
     public static void ShowDirectory(ListView lview, string path)
     {
      
    
     }
    Thanks for help in advance, I hope you understood me.

  2. #2
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,299

    Re: Pass control of another form to void ?

    What you're talking about in VB is a default instance and they don't exist in C#. They haven't always existed in VB either. If you're not completely au fait with default instances then I suggest that you follow the Blog link in my signature below and check out my post on the subject. If you really want to go that way, which I would recommend against, then you might also follow the CodeBank link in my signature and check out my thread on simulating default instances in C#.

    As for the proper way to do this in C# (and in VB for that matter), it depends on exactly what you're trying to achieve, i.e. why you want to pass this ListView into this method in the first place. Exactly how best to implement this depends on exactly what you're trying to achieve and, most importantly, the relationship between the forms. For one thing, the field added to a form class when you add a control in the designer is 'private' by default, which means that it can't be accessed from outside the form. You can change that of course, but you really shouldn't. That means that even if Form1 creates Form2 and passes a reference to itself into that Form2 instance, the ListView still remains inaccessible.

    If you provide a FULL and CLEAR explanation of what you're trying to achieve, including the relationship between the forms and that method, then I'll provide some specific options, including the easiest and the best, as in the one that follows accepted best practice.

    By the way, it's not "a void", it's a method with a return type of void, which is equivalent to a VB Sub. Just call it a method because that's what it is. The return type is irrelevant in this case.

  3. #3

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2016
    Location
    Slovenia
    Posts
    575

    Re: Pass control of another form to void ?

    If you really want to go that way, which I would recommend against, then you might also follow the CodeBank link in my signature and check out my thread on simulating default instances in C#.
    Thanks for response JM, but what thread is that, I can't find It in Codebank link. Or at least I wasn't looking at the right ones. I've read all your Blog articles about instances though.

    If you provide a FULL and CLEAR explanation of what you're trying to achieve, including the relationship between the forms and that method, then I'll provide some specific options, including the easiest and the best, as in the one that follows accepted best practice.
    Ok, no problem. The thing is this - I have a listview on multiple forms, It's a file manager, so I'm displaying filesystem directories in them. To avoid same code in all those forms I created a module (in VB.NET) and a Sub which tells what directory to show in which Listview, that's It. And in one case I need to call code from a Form1 to show filesystem directory in a Form2 Listview, that's the whole point.

    Now reading all your stuff I still can't figure out a simple way in C# to do this. Should I write a method class to pass control over from different form ?

    Here's my void - full code, If It will help understand:
    Code:
    public void ShowDirectory(ListView lview, string path)
    {
    	
    	dynamic dir_items = new DirectoryInfo(path);
    	
    	PropertyFolder = shell.NameSpace(path);
    
    	lview.Items.Clear();
    
    	List<ListViewItem> items = new List<ListViewItem>();
    	Dictionary<string, string> dicTypes = new Dictionary<string, string>();
    
    	foreach (DirectoryInfo folder in dire_items.EnumerateDirectories) {
    	
    		ListViewItem lview_folder = new ListViewItem();
    
    	
    		lview_folder.Tag = folder.FullName;
    		lview_folder.Text = folder.Name;
    
    		if (!dicTypes.ContainsKey(folder.Extension)) {
    	                //folder properties
    			prop = PropertyFolder.ParseName(Path.GetFileName(folder.FullName));
    			dicTypes.Add(folder.Extension, PropertyFolder.GetDetailsOf(prop, 2).Trim());
    		}
    
    		lview_folder.ImageKey = "folder";
    
    		lview_folder.SubItems.Add(folder.LastWriteTime.ToShortDateString() + " " + folder.LastWriteTime.ToShortTimeString());
    		lview_folder.SubItems.Add(dicTypes(folder.Extension));
    		items.Add(lview_folder);
    
    	}
    
    	foreach (FileInfo file in dir_items.EnumerateFiles()) {
    			
    		ListViewItem lview_file= new ListViewItem();
    		
    		lview_file.Tag = file.FullName;
    		lview_file.Text = file.Name;
    
    		if (!(MyImageList.Images.ContainsKey(file.Extension))) {
    			iconForFile = System.Drawing.Icon.ExtractAssociatedIcon(file.FullName);
    			MyImageList.Images.Add(file.Extension, iconForFile);
    		}
    
    		if (!dicTypes.ContainsKey(file.Extension)) {
    			//file properties
    			prop = PropertyFolder.ParseName(Path.GetFileName(file.FullName));
    			dicTypes.Add(file.Extension, PropertyFolder.GetDetailsOf(prop, 2).Trim());
    		}
    	
    		lview_file.ImageKey = file.Extension;
    		lview_file.SubItems.Add(file.LastWriteTime.ToShortDateString() + " " + file.LastWriteTime.ToShortTimeString());
    		lview_file.SubItems.Add(dicTypes(file.Extension));
    	        lview_file.SubItems.Add(LastnostiMape.GetDetailsOf(Lastnosti, 1).Trim());
    		items.Add(lview_file);
    
    	}
    
    	lview.SuspendLayout();
    	lview.BeginUpdate();
    
    	lview.Items.AddRange(items.ToArray());
    
    	lview.EndUpdate();
    	lview.ResumeLayout();
    	
    }

  4. #4
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,299

    Re: Pass control of another form to void ?


  5. #5

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2016
    Location
    Slovenia
    Posts
    575

    Re: Pass control of another form to void ?

    Fantastic thread JM, will find It very useful for future projects, but I'm still having difficulties to reference a control within form instance which I will need for my void in post #3. I'm struggling to get It to work in many ways, but I'm obviously doing something completely wrong. Here is my latest try:

    Code:
    public class SinglePattern<TForm> where TForm : Form, new()
        {
            private static TForm _instance;
    
            public static TForm Form
            {
                get
                {
                    if (_instance == null || _instance.IsDisposed)
                    {
                        _instance = new TForm();
                    }
                    return _instance;
                }
            }
            
            public static Control ctl(string ctl_name)
            {
                return _instance.Controls[ctl_name];
            }
        }
    testing:

    p
    Code:
    rivate void button1_Click(object sender, EventArgs e)
            {
               var d= SingleLviewPattern<Form1>.ctl("listView1");
                MessageBox.Show(d.Name);
    
            }
    Error is ofcourse: "object reference not set to an instance...". Can you help me with It ?

  6. #6
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,299

    Re: Pass control of another form to void ?

    Firstly, I can't see any reason for your having changed the name of the class from FormSingleton to SinglePattern. That's not inherently wrong but it seems rather arbitrary, particularly given that the new name is less informative than the old.

    As for the issue, I've just put together a little demo. Firstly, the point of the Singleton pattern is that there's a single instance of the type. I'm guessing that Form1 is your startup form so you would need to show that single instance as your startup form if you want it to be useful later on. There's no point showing one instance first and then trying to access a control on another instance later. Here's the contents of the code file for the singleton class:
    csharp Code:
    1. using System.Windows.Forms;
    2.  
    3. namespace WindowsFormsApp1
    4. {
    5.     public static class FormSingleton<TForm> where TForm : Form, new()
    6.     {
    7.         private static TForm _instance;
    8.  
    9.         public static TForm Form
    10.         {
    11.             get
    12.             {
    13.                 if (_instance == null || _instance.IsDisposed)
    14.                 {
    15.                     _instance = new TForm();
    16.                 }
    17.  
    18.                 return _instance;
    19.             }
    20.         }
    21.  
    22.         public static void Show()
    23.         {
    24.             Form.Show();
    25.             Form.Activate();
    26.         }
    27.     }
    28. }
    Here's the default code that creates and displays the startup form in the Program.cs code file:
    csharp Code:
    1. using System;
    2. using System.Windows.Forms;
    3.  
    4. namespace WindowsFormsApp1
    5. {
    6.     static class Program
    7.     {
    8.         /// <summary>
    9.         /// The main entry point for the application.
    10.         /// </summary>
    11.         [STAThread]
    12.         static void Main()
    13.         {
    14.             Application.EnableVisualStyles();
    15.             Application.SetCompatibleTextRenderingDefault(false);
    16.             Application.Run(new Form1());
    17.         }
    18.     }
    19. }
    That would need to be changed to make use of the singleton form:
    csharp Code:
    1. using System;
    2. using System.Windows.Forms;
    3.  
    4. namespace WindowsFormsApp1
    5. {
    6.     static class Program
    7.     {
    8.         /// <summary>
    9.         /// The main entry point for the application.
    10.         /// </summary>
    11.         [STAThread]
    12.         static void Main()
    13.         {
    14.             Application.EnableVisualStyles();
    15.             Application.SetCompatibleTextRenderingDefault(false);
    16.             Application.Run(FormSingleton<Form1>.Form);
    17.         }
    18.     }
    19. }
    Later on, you can access a control by name like this:
    csharp Code:
    1. var lv = FormSingleton<Form1>.Form.Controls["listView1"] as ListView;
    Personally, I wouldn't add that Control method to the singleton class because it's not really it's responsibility. The point of that class is the singleton behaviour. What you want to do with that single instance is your own business and belongs outside that class.

  7. #7

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2016
    Location
    Slovenia
    Posts
    575

    Re: Pass control of another form to void ?

    Thanks for an excellent explanation JM, now I understand It.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width