Why is this call not passing the information from my xml file to the winForm?

107 views Asked by At

I'm a NEWB and I'm lost. I beg your patience.

I have a working application where I believe I am serializing (??) xml file data using the following code.

    public static string elementUser(object sender)
    {
        XmlDocument xmldoc = new XmlDocument();

        //**EDIT:** This is where I would call 
        //locateFolder(sender, xmldoc);
        //instead of fileExistsRequest(xmldoc);

        fileExistsRequest(xmldoc);

        XmlNodeList nodelist = xmldoc.SelectNodes("//Name");

        foreach (XmlNode xmlnode in nodelist)
        {
            if (xmlnode["User"] != null)
            {
                usertxt = xmlnode["User"].InnerText;                
            }

            else
            {
            }
            return usertxt;
        }
        return usertxt;            
    }

After calling this I load the contents of the xml element in a winForm for display to the user to manipulate. Other forms will call other elements. Ex Math.cs will call only <Start> <End> or <Ticks> for use in other dialogs.

The above was designed to work on one xml file with one entry (??) which looks like this

<?xml version="1.0" encoding="utf-8"?>
<SubmitTime12>
  <Name Key="11/18/2014">
    <User>fpytel</User>
    <Date>11/18/2014</Date>
    <JobNum>00000</JobNum>
    <RevNum>CR8</RevNum>
    <Task>why</Task>
    <Start>00:00 AM</Start>
    <End>8:00 AM</End>
    <Ticks></Ticks>
    <Explanation>Expletives Abound</Explanation>
  </Name>
</SubmitTime12>

It occurred to me that I could use elementUser(object sender) to load other xml files with the same basic format, but with more entries. Really the only change would be that the <User> is not included in the Reportfpytel.xml file entries as the user is part of the file name. Ex:

...
<Name Key="11/14/2014 6:45:57 AM">
  <Date>11/3/2014</Date>
  <JobNum>00000</JobNum>
  <RevNum>00000</RevNum>
  <Task>Testing less</Task>
  <Start>4:00 AM</Start>
  <End>4:00 AM</End>
  <TotalTime></TotalTime>
</Name>
<Name Key="11/14/2014 6:46:39 AM">
  <Date>11/13/2014</Date>
  <JobNum>26356</JobNum>
  <RevNum>00000</RevNum>
  <Task>Red Lines</Task>
  <Start>2:00 AM</Start>
  <End>2:00 AM</End>
  <TotalTime></TotalTime>
</Name>
...

So in the first code above I replaced fileExistsRequest(xmldoc); with the following call by creating it in the elementUser(object sender); and refactoring it out of the code. This is what was supplied by VS2010.

    public static void locateFolder(object sender, XmlDocument xmldoc)
    {
        string senderName = sender.ToString();
        if (senderName == "Start")
        {

        }
        else if (senderName.Contains("ApproveTime"))
        {
            fileExistsRequest(xmldoc);
        }
        else if (senderName.Contains("Report"))
        {
            fileExistsReport(xmldoc);
        }
        else if (senderName == "Math")
        {
            fileExistsReport(xmldoc);
        }
    }

This works without error but will not load the elements to the controls on the calling form. I stepped through every line from the time it is called (either onLoad or onShown) and it finds the folder, finds the file, finds the element, assigns the element to a string and gets ready to feed the string to the control on the calling form. When I take the final step to bring it to the form it clears the string to "" and shows the calling form with blank fields.

If I put a break in the locateFolder(object sender, XmlDocument xmldoc) function and try to step past this

        string senderName = sender.ToString();

I get a NullReferenceException error with tips new keyword and checking if the object is null. That's the only error I can find that is giving me a hint. Almost like it's loading the strings into the controls and then emptying the contents again. What I don't understand is why it works just fine without the locateFolder() call and why no error is thrown when I do not place a break in the code to try to find the error. Like I said, I have made that call on the Shown event as well as the Load event.

Is there anyone that understands what's going on here. I really would like to reuse this code.

EDIT2: Modified per JTMon to try to catch the null exception. It ran right past it. Did I have it configured correctly??

    public static void locateFolder(object sender, XmlDocument xmldoc)
    {
        //XmlDocument xmldoc1 = new XmlDocument();
        try
        {
            string senderName = sender.ToString();
            if (senderName == "Start")
            {

            }
            //...OriginalCode
        }
        catch
        {
            if (sender == null)
            {
                MessageBox.Show("returned null");
            }
        }
        finally
        {
            if(sender == null)
            {
                MessageBox.Show("returned null");
            }
        }
    }

EDIT3 Per Galdo I changed the code to this.

    public static void locateFolder(object sender, XmlDocument xmldoc)
    {
        if (sender != null)
        {
            string senderName = sender.ToString();
            if (senderName == "Start")
            {

            } 
         //...OriginalCode
        }
        else
        {
            MessageBox.Show("returned Null");
        }
    }

My error has cleared up. Both JTMon's and Galdo's suggestion has cleared the error, but it is still not passing the values to the sender form textbox.

Thank you all very much for commenting. I'm trying to keep up. Thanks!!

EDIT4 Per request from Kristof. The call from the sender of elementUser();

    private void ApproveTime_Load(object sender, EventArgs e)
    {
        Start p = (Start)this.Owner;
        Control[] c = p.Controls.Find("bApproveTime", false);
        Button b = (Button)c[0];
        b.Enabled = false;


        WidgetLogic.elementUser(this);
    }
1

There are 1 answers

5
Kristof On BEST ANSWER

Okay, finally getting to something that might be a solution to your problem.
The "this" in this line of code :

WidgetLogic.elementUser(this);

is the class that contains the void ApproveTime_Load.
I'm hoping that class is a form.(if not please specify the class)
The problem with your code is that you're passing this into the function elementUser as an object and later on casting it as a string. Could you pass a string into this function instead of an object?
Assuming "this" is a form it should look like this :

WidgetLogic.elementUser(this.Text);

You could then refactor your elementUser and following functions to not take a sender object but a sender string(which makes a bit more sense).
The word sender is usually used as an object because you pass the calling button or form.
You could still pass the actual sender but then you can just do toString. You'd have to cast the sender object to a form and get the Text property.