【问题标题】:Unable to change label text when Invoking Method through Reflection in c#在c#中通过反射调用方法时无法更改标签文本
【发布时间】:2016-12-08 09:15:45
【问题描述】:

先看我的代码

namespace HealthClub
{
    public partial class frmTrainerMaster : Form
    {
        DataTable dt = new DataTable();
        frmHome Home = new frmHome();
        public frmTrainerMaster()
        {
            InitializeComponent();            
        }
    }

    private void frmTrainerMaster_Load(object sender, EventArgs e)
        {            
            FillValues("UserNameText");            
        }


   public void FillValues(string UserName)
    {
        DataTable DT;
        SqlCommand cmd = new SqlCommand();
        try
        {
            cmd.Connection = Connections.Connection[UserName];
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.CommandText = "TrainerMaster_pro";
            cmd.Parameters.AddWithValue("Option", "FillValues".Trim());
            if (Connections.Connection[UserName].State == ConnectionState.Closed)
                Connections.Connection[UserName].Open();
            SqlDataAdapter adp = new SqlDataAdapter(cmd);
            DT = new DataTable();
            adp.Fill(DT);
            lblId___.Text = DT.Rows[0][0].ToString();                
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString());
        }
        finally
        {
            cmd.Parameters.Clear();
            cmd.Dispose();
            Connections.Connection[UserName].Close();                
        }
    }
}

现在我正在像这样的另一个类中调用 FillValues()

class AnotherClass
{
public void TestMethod(string FormName)
{
    Type tp = Type.GetType("HealthClub." + FormName);
                object myobj = Activator.CreateInstance(tp);
                MethodInfo method = myobj.GetType().GetMethod("FillValues");
                object[] parametersArray = new object[] { UserName };
                method.Invoke(myobj, parametersArray);    
}
}

如果您查看 FillValues(),我将数据库值分配给标签。当我在页面加载的第一堂课中调用它时,它工作正常。

但是当我从第二类调用方法时,方法调用但数据库值没有分配给标签。

我需要做哪些额外的努力?

【问题讨论】:

  • 好吧,您正在创建表单的新实例 - 但从未真正显示它。我的猜测是您应该使用表单的 existing 实例...
  • 你能简单介绍一下吗?
  • 嗯,我已经解释了我能做的一切——我不知道我还能说什么。如果您从不显示表单,那么创建表单就没有多大意义,而这正是您目前正在做的事情。
  • 你的意思是我必须在调用方法时传递现有的第一类实例?
  • 是的。否则,您如何期望知道您要填充哪种表单?

标签: c# .net reflection


【解决方案1】:

有一个类,有一个实例。这是您需要了解的非常基本的概念(不仅在 C# 中,而且在任何面向目标的语言中)。

// class example
class FrmTrainerMaster  { public int SomeProperty { get; set;} }

当您创建新实例时:

// creates one window
var frmTrainerMasterInstanceOne = new FrmTrainerMaster();
frmTrainerMasterInstanceOne.SomeProperty = 1; 

// creates second window
var frmTrainerMasterInstanceTwo = new FrmTrainerMaster();
frmTrainerMasterInstanceTwo.SomeProperty = 2;

实例是独立的 - 所以此时查询

// will return 1 
Console.Out.WriteLine(frmTrainerMasterInstanceOne.SomeProperty);
// will return 2 
Console.Out.WriteLine(frmTrainerMasterInstanceTwo.SomeProperty);

反射var myobj = Type.GetType("HealthClub.FrmTrainerMaster"); 等于var myobj = new FrmTrainerMaster();,所以通过myobj 做任何事情,你仍然不能影响frmTrainerMasterInstanceOnefrmTrainerMasterInstanceTwo

您实际上需要的是方法如何将实例(FrmTrainerMaster 类)的引用传递到您需要它的地方(我们称之为AnotherForm),没有给定类的所有实例的神奇列表,除非你明确地构建它。

public partial class FrmTrainerMaster : Form
{
  public void FillValues(string userName) { ... }
}

一种方法是通过构造函数注入(通常提供 - 因为在构造对象 (AnotherForm) 时,它处于有效状态(即所有依赖项都已初始化)。

public class AnotherForm : Form {
   private readonly FrmTrainMaster _frmTrainMaster;
   public AnotherForm(FrmTrainMaster frmTrainMaster) {
     if (frmTrainMaster == null) {
       throw new ArgumentNullException(nameof(frmTrainMaster));
     }
     _frmTrainMaster = frmTrainMaster;
   }
}

或者通过setter注入:

public class AnotherForm : Form {
  private FrmTrainMaster _frmTrainMaster;
  public FrmTrainMaster MasterForm { set { _frmTrainMaster = value; } }
}

无论哪种方式,反射都不是必需的。您可以在AnotherForm 的任何地方拨打电话

class AnotherForm : Form {
  ...
  public void FooMethodThatCallFillValues() {
    _frmTrainMaster.FillValues("...");
  }
}

【讨论】:

  • 感谢@Ondrej 的回答。实际上,我通过将类名发送到AnotherClass 来调用FillValues()。那么我怎样才能在没有反射的情况下调用它呢?我编辑了我的问题
  • @ShaiwalTripathi - 你不能只发送类名 - 你需要发送对类实例的引用。查看我的更新。
  • 我动态地将表单名称发送到AnotherForm,例如从ThirdClass 发送frmTrainerMaster。所以正如你所说,我必须将实例引用发送到AnotherClass。但是我将如何在 ThirdClass 中获得参考,以便将其传递给 AnotherForm ?你能给我一个例子吗?我褪色了..
  • @ShaiwalTripathi - 我建议重新表述您的问题并分享您想要实现的目标。
  • 嗨@Ondrej 我问了一个新问题,它会让你明白一切。请问你能看一下吗? stackoverflow.com/questions/41136940/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多