communicate or access a parent from another using c#

旧巷老猫 提交于 2019-12-02 06:51:51

Robert's answer is correct as far as accessing members on another form. However, in general you should be storing the state of your application (call it the "model") separately from the state of your user interface (call it the "view"). This becomes very important as your application grows beyond one or two interactions. There are several philosophies or patterns about how to tie the two together (Google "model-view-controller" (MVC) and "model-view-viewmodel" (MVVM) for example), and if you really want to do this correctly I would recommend learning about those. My preference is for the MVVM approach, and you can do it fairly easily with Windows Forms even though it was designed with WPF applications in mind.

In .NET, the basic piece of code you should use to implement the connection between your viewmodel and your view is an interface called INotifyPropertyChanged. You create a class that implements this interface and sends notifications whenever a property changes, so for example for your path property you would create this class:

class ViewModel : INotifyPropertyChanged
{
    private string path;
    public string Path
    {
        get { return path; }
        set {
            if (value != path)
            {
                path = value;
                NotifyPropertyChanged();
            }
        }
    }

    // This event gets triggered whenever a property changes.
    public event PropertyChangedEventHandler PropertyChanged;

    // This will cause the event to actually be triggered. It automatically determines the name of the property that triggered it using the [CallerMemberName] attribute - just a bit of .NET 4.5 sweetness. :)
    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

It may seem like a lot of work, but now in your form1 you can create a new "ViewModel" instance, subscribe to the event, and then pass the instance to form2. form2 then simply updates the Path property on the viewmodel instance whenever the user selects a different path.

So, Form1 needs this code near the top:

private ViewModel viewmodel = new ViewModel();

And this goes in the Form1 constructor:

viewmodel.PropertyChanged += new EventHandler(OnPathChanged);

And when you create/show form2:

var form2 = new Form2(viewmodel); // Note, the viewmodel instance is being passed to the form2 constructor
form2.Show();

The form2 constructor then stores its own reference to the "viewmodel" instance, and sets the Path property whenever the path is changed by the user.

private ViewModel viewmodel;

public Form2(ViewModel viewmodel)
{
    this.viewmodel = viewmodel;
    ... // Other stuff to set up your controls etc. goes here
}

private void PathChanged(object sender, EventArgs e) // This may be named differently in your code; it's the event handler that gets called when the path changes
{
    // This will automatically notify the event handler in Form1! It's super-elegant and flexible.
    this.viewmodel.Path = txtPath.Text; // Assuming you have a textbox called txtPath
}

And finally the event handler in Form1:

private void OnPathChanged(object sender, EventArgs e)
{
    var newPath = viewmodel.Path; // Get the updated path back from the viewmodel
    //TODO: Whatever you want to do when the path changes.
}

Here's a link to a really good MVVM intro using Windows Forms, it uses two forms like you have in your example. MVVM (Model-View-ViewModel) Pattern For Windows Form Applications, using C#

Robert Harvey

If you need to access something on another form, just hold a reference to it from your first form, like this:

form2 = new Form2();
form2.Show();
form2.WhateverYouWantToAccess

That said, if you just want to get a file path from the user, you want to use the OpenFileDialog class.

private void button1_Click(object sender, System.EventArgs e)
{
    Stream myStream = null;
    OpenFileDialog openFileDialog1 = new OpenFileDialog();

    openFileDialog1.InitialDirectory = "c:\\" ;
    openFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*" ;
    openFileDialog1.FilterIndex = 2 ;
    openFileDialog1.RestoreDirectory = true ;

    if(openFileDialog1.ShowDialog() == DialogResult.OK)
    {
        try
        {
            if ((myStream = openFileDialog1.OpenFile()) != null)
            {
                using (myStream)
                {
                    // Insert code to read the stream here.
                }
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message);
        }
    }
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!