繁体   English   中英

在C#中通过反射调用方法时,无法更改标签文本

[英]Unable to change label text when Invoking Method through Reflection in c#

首先看一下我的代码

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(),则将数据库值分配给标签。 当我在页面加载的第一堂课中调用它时,它工作正常。

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

我需要做些什么额外的努力?

有一个类,有一个实例。 这是您需要理解的非常基本的概念(不仅是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实例的引用传递给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;
   }
}

或通过二传手注射:

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

无论哪种方式,反射都是根本不需要的。 在您的AnotherForm任何地方,您都可以致电

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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