簡體   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