开发者

c# - WPF command-line argument for opening file gives infinite loop

This is a weird one! I am working on an application that reads vCard files, which contain contact etc. information for a person. Each file may contain separate 'sections' that each contain the details for one person, which are separated by BEGIN:VCARD [data here] END:VCARD.

To enable my users to view all of the different details, I've allowed my program to populate the textboxes in my app with the details and then open a new Window and do this with that one, but for each of the different sections in the file.

The problem comes about when my program opens when a vCard file has been double clicked in Explorer. It keeps looping through the vCard. I don't know what to do, but below is my problematic code:

    public void readVcard(string fname)//Reads vCard and then loops through sections
    {
        try
        {
            using (StreamReader r = new StreamReader(fname))
            {
                string input = F开发者_如何学Cile.ReadAllText(fname);//read through file

                String[] vArray = input.Split(new string[] { "BEGIN:VCARD" }, StringSplitOptions.None);

                int i;

                for (i = 1; i < vArray.Length; i++)
                {
                    MainWindow a = new MainWindow();
                    a.parser(vArray[i]); //Parser is the function that populates the app
                    a.Show();
                }

                return;
            }
        }...

This function is called from here:

    void MainWindow_Loaded(object sender, RoutedEventArgs e)//Processes a file when opened externally
    {
        if (Application.Current.Properties["ArbitraryArgName"] != null)
        {
            string fname = Application.Current.Properties["ArbitraryArgName"].ToString();

            readVcard(fname);

        }
    }

If anyone could help, it would be greatly appreciated.


I think that Artyom is on the right track.

Every time you create another MainWindow and load it you will be getting the current applications argurment and jumping back in to readVcard, which will process the same vCard that you are already processing and open yet another MainWindow which will continue the process.

Consider moving all of the code you have inside of MainWindow_Loaded() to the Startup event for your application. That way it will only get called once when your program first loads, instead of every time you create a new window.

To do this you need to register for the event in your App.xaml file like so:

<Application x:Class="MyProgram.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Startup="Application_Startup">
</Application>

And then in the code behind App.xaml you put your code for reading the vCard. Like this:

namespace MyProgram
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        private void Application_Startup(object sender, StartupEventArgs e)
        {
            if (Application.Current.Properties["ArbitraryArgName"] != null)
            {
                string fname = Application.Current.Properties["ArbitraryArgName"].ToString();

                readVcard(fname);

            }
        }
    }
}


When you create and show new MainWindow (a.Show()), the MainWindow_Loaded event fires again and it again calls a readVcard method. So there is an infinite loop.

Or may be not really infinite, because, I belive, some time later a StackOverflowException may happen.

You just need to review startup logic, so readVcard will launch not in the MainWindow_Loaded event, but, for example, in the Main method (in program.cs file). Or you may add some flag, which will be set when readVcard method first called.


I get it! I've now got the following code in App.xaml.cs:

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        if (e.Args != null && e.Args.Count() > 0)
        {
            this.Properties["ArbitraryArgName"] = e.Args[0];
        }
        base.OnStartup(e);

        if (Application.Current.Properties["ArbitraryArgName"] != null)
        {
            string fname = Application.Current.Properties["ArbitraryArgName"].ToString();

            MainWindow mw = new MainWindow();
            mw.readVcard(fname);

        }
    }

}

It works fine! Thanks everyone. BTW the following blog contains the command-line info I originally used if anyone needs it: http://blogs.msdn.com/b/avip/archive/2008/10/27/wpf-supporting-command-line-arguments-and-file-extensions.aspx.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜