为什么这个调用没有将我的xml文件中的信息传递给winForm?

时间:2014-11-19 13:00:15

标签: c# xml code-reuse

我是NEWB而且我迷路了。请耐心等待。

我有一个工作应用程序,我相信我使用以下代码序列化(??)xml文件数据。

    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;            
    }

调用它之后,我在winForm中加载xml元素的内容,以显示给用户进行操作。其他形式将调用其他元素。 Ex Math.cs将仅调用<Start> <End><Ticks>以用于其他对话框。

以上设计用于处理一个xml文件,其中一个条目(??)看起来像这样

<?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>

我想到我可以使用elementUser(object sender)加载其他xml文件,这些文件具有相同的基本格式,但有更多条目。实际上唯一的变化是<User>文件条目中不包含Reportfpytel.xml,因为用户是文件名的一部分。例如:

...
<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>
...

因此,在上面的第一个代码中,我通过在fileExistsRequest(xmldoc);中创建它并将其重构为代码,将elementUser(object sender);替换为以下调用。这是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);
        }
    }

这没有错误,但不会将元素加载到调用表单上的控件。我从调用它(onLoad或onShown)开始逐步执​​行每一行,它找到文件夹,找到文件,找到元素,将元素分配给字符串并准备将字符串提供给调用的控件形成。当我采取最后一步将其带到表单时,它将字符串清除为“”并显示带有空白字段的调用表单。

如果我暂停locateFolder(object sender, XmlDocument xmldoc)功能并试图超越此

        string senderName = sender.ToString();

我收到NullReferenceException错误,其中包含提示new关键字并检查对象是否为空。这是我能找到的唯一一个给我提示的错误。几乎就像它将字符串加载到控件中,然后再次清空内容。我不明白的是,为什么没有locateFolder()调用就可以正常工作,为什么当我不在代码中设置中断以尝试查找错误时,不会抛出任何错误。就像我说的那样,我已经对Shown事件以及Load事件进行了调用。

有没有人了解这里发生的事情。我真的想重用这段代码。

EDIT2:根据JTMon修改以尝试捕获空异常。它跑过去了。我的配置是否正确?

    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 每个Galdo我将代码更改为此。

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

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

我的错误已经清除。 JTMon和Galdo的建议都清除了错误,但它仍未将值传递给发件人表单文本框。

非常感谢你们的评论。我想跟上。谢谢!

EDIT4 根据Kristof的要求。来自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 个答案:

答案 0 :(得分:1)

好的,最后找到可能解决问题的方法 这段代码中的“this”:

WidgetLogic.elementUser(this);

是包含void ApproveTime_Load的类 我希望课程是一种形式。(如果没有,请指明课程)
你的代码的问题在于你将它作为一个对象传递给函数elementUser,然后将它作为一个字符串转换。 你能把字符串传递给这个函数而不是一个对象吗? 假设“this”是一个表单,它应该是这样的:

WidgetLogic.elementUser(this.Text);

然后,您可以重构您的elementUser和以下函数,不使用发送方对象,而是使用发送方字符串(这更有意义)。
单词sender通常用作对象,因为您传递了调用按钮或表单 您仍然可以传递实际的发件人,但之后您可以执行toString。您必须将发件人对象强制转换为表单并获取Text属性。