简体   繁体   中英

accessing non-static method from another class without instantiate

Title is my question. I will explain below.

I am working on wpf application is vs2010. I have two windows, one is my MainWindow and another is a fileList window. In my fileList window, I have a list of files, which on click, should load the file. The onClick method is implemented in fileList class. The function to load the file is implemented in MainWindow partial class.

My fileList class in instantiated in MainWindow class to show the window. I cant instantiate MainWidow again. The function(method) in MainWindow can't be declared static because it uses other parameter which I can't (don't know how to) declared static.

I am pasting relevant code below. Kindly help.

namespace test
{
  public partial class MainWindow : Window
     fileList fl = new fileList;

     public MainWindow()
     {
      InitializeComponent();
      fl.show();
      }

      public void porcessfile(string path)
      {
       //this method processes the the file at "path". It uses combobox and scrollviewer 
       //declared in xaml. I dont know how to declare static in xaml, else I will declare       
       //them static and change the whole method to static, so I can call it without  
       //instantiating. I tried making a nested-class, but then I can't  access variable 
       //declared in MainWindow (parent) class. Or there is a way to do that?

      }
}

and the other class:

namespace test
{
  public partial class fileList : Window
  {
     public fileList()
     {
        IntializeComponent();
     }



     private void Button_click(object sender, RoutedEventsArgs e)
     {
      //code that gets "path" on click, works fine.

      processfile(string path); // what and how to do here.
     }
  }

} 

I sincerely hope I am clear. Please ask details if required.

Well, the easiest solution would be to simply give your Filelist window a constructor which accepts an delegate which points to your processfile method in the Mainwindows. Look at this article: http://www.codeproject.com/Articles/109000/C-Delegates-Step-by-Step

Making it statis is not the solution -it would be a very ugly hack, which causes more trouble than the delegate.

There is a static convenience access property for all windows in your application:

Application.Current.Windows

Then simply take the first one (or figure out the right one if you have more then one) and cast to your MainWindow type. And now you have an instance to call your method.

Ok, this should be fairly easy. You just need to declare an event in your FileList class which fires in your Button_click method sending the file path and subscribe to it from MainWindow, and call your processfile method with the argument you've just received.

In your FileList class:

    public event EventHandler<EventArgs<string>> PathReceived = delegate { };

Publish this in your Button_click.

In your MainWindow class on cosntructor:

   this.fileList.PathReceived = (o,args) => this.ProcessFile(args.Value);

Publish code:

   this.PathReceived(null, new EventArgs<string>(yourPath));

EDIT: I forgot to provide you with the EventArgs class (it's from an old project of mine).

public class EventArgs<T> : EventArgs
{
    /// <summary>
    /// Initializes a new instance of the <see cref="EventArgs{T}"/> class.
    /// </summary>
    /// <param name="value">The value.</param>
    public EventArgs(T value)
    {
        Value = value;
    }

    /// <summary>
    /// Gets the value.
    /// </summary>
    /// <value>
    /// The value.
    /// </value>
    public T Value { get; private set; }
}

Although it's something of an anti-pattern (because it resembles global variables and persists state, which makes testing more difficult), you can use the singleton pattern here:

public partial class MainWindow {
  private static MainWindow instance = new MainWindow();

  public static MainWindow Instance { get { return instance; } }

  private FileList fl = new fileList();

  private MainWindow() {
    InitializeComponent();
    fl.show();
  }
}

Your file list can then use MainWindow.Instance .

But, this has the side-effect of partially hiding dependencies between the two classes. What you really want to do is require a MainWindow instance in the constructor to fileList . That keeps the dependencies obvious, and opens the door to using a framework (which will help you with testability).

Also, the C# convention is to call the class FileList and not fileList .

我这样做是为了让一种方法可以在我的一个类中运行,而无需进行整个变量设置。

string res = (new myClass ()).methodInsideMyclass ();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM