2016-09-25 62 views
-4

我有2種形式:表格A和表格B.我也有一個屬性字段類。通過物業變更價值

表單A包含我想在屬性發生更改時更改的標籤。表格B包含將改變屬性字段的代碼。

屬性類代碼:

public class Controller 
    { 
     private static string _customerID; 
     public static string customerID 
     { 
      get { return _customerID; } 
      set 
      { 
       _customerID = value; 
       if (_customerID != "") 
       { 
        FormA.ChangeMe(); 
       } 
      } 
     } 
    } 

形式B編碼:

private void something_Click(object sender, SomethingEventArgs e) { 
    Controller.customerID = "Cool"; 
} 

形式A代碼:

public static void ChangeMe() 
     { 
      var frmA = new FormA(); 
      MessageBox.Show("Test: " + Controller.customerID); //This works! Shows Cool 
      frmA.lb2Change.Text = Controller.customerID; //This kind of works.. 
      MessageBox.Show("Test2: " + frmA.lb2Change.Text); //This shows the correct value. Shows Cool 
     } 

的屬性字段值被傳遞(這是我從在MessageBox知道),但它不會更新表單標籤本身的值。爲什麼是這樣?我究竟做錯了什麼?我也相信有一個更好的替代方案來實現ChangeMe()方法的意圖實現 - 如果有的話,是否有任何建議?

+0

如前所述,因爲你正在改變一個屬性值'frmA'的新實例,而不是已經存在的實例以及用戶實際使用的實例,用戶當然不會看到新值。請參閱https://stackoverflow.com/questions/32816542/c-sharp-cant-change-labels-and-button-properties-from-a-dialogbox查看堆棧溢出的許多類似問題之一,解決這個問題,常見錯誤。 –

+0

就各種對象互動而言,您有各種各樣的選擇,所有這些選項都可以避免讓每個班級實際上需要知道關於另一個班級的任何具體內容。一種選擇是實現'INotifyPropertyChanged'並在需要通知的類中訂閱'PropertyChanged'。有關其他建議,請參閱https://stackoverflow.com/questions/1665533/communicate-between-two-windows-forms-in-c-sharp。同樣,堆棧溢出已經存在很多關於這些概念的問題。 –

回答

0

在您的靜態方法ChangeMe中,您每次都要創建一個新窗體,您要更改該值。而不是你想改變現有表單的價值。因此,你的控制器需要這個FormA的實例。試着這樣說:

public class Controller 
{ 
    //You can pass the form throught the constructor, 
    //create it in constructor, ... 
    private FormA frmA; 

    private string _customerID; 
    public string customerID 
    { 
     get { return _customerID; } 
     set 
     { 
      _customerID = value; 
      if (_customerID != "") 
      { 
       frmA.ChangeMe(); 
      } 
     } 
    } 
} 

現在你鴕鳥政策需要是靜態的你FormA

public void ChangeMe() 
{ 
    MessageBox.Show("Test: " + Controller.customerID); 
    this.lb2Change.Text = Controller.customerID; 
} 
+0

雖然你的代碼可以工作,但是你的代碼非常髒,並且不能**可重用**並且不支持代碼分離。國際海事組織,你不應該推薦這樣的解決方案,你控制器類嚴格依賴於'formA',如果有其他'形式'和'用戶控件'和'類'使用這個'控制器類?你將在控制器類中定義它們全部? – Monah

+0

基本上你是對的。但NuWin已經與靜態運算符和類的實例結合在一起了。當然,你的解決方案好得多,但在這一點上太複雜了。 – Fruchtzwerg

+0

@Fruchtzwerg這實際上不起作用。我在控制器類的frmA.ChangeMe()上得到'System.NullReferenceException'。 – NuWin

1

你可以做以下

  1. 要定義一個委託
  2. 實施財產變更通知

代表

public delegate void OnCustomerIDChanging(object sender,CancelEventArgs e); 
public delegate void OnCustomerIDChanged(object sender,object value); 
public class Controller 
{ 
    private static string _customerID; 
    public event OnCustomerIDChanging CustoerIDChanging; 
    public event OnCustomerIDChanged CustoerIDChanged; 
    public static string customerID 
    { 
     get { return _customerID; } 
     set 
     { 
      // make sure that the value has a `value` and different from `_customerID` 
      if(!string.IsNullOrEmpty(value) && _customerID!=value) 
      { 
       if(CustomerIDChanging!=null) 
       { 
        var state = new CancelEventArgs(); 
        // raise the event before changing and your code might reject the changes maybe due to violation of validation rule or something else 
        CustomerIDChanging(this,state); 
        // check if the code was not cancelled by the event from the from A 
        if(!state.Cancel) 
        { 
         // change the value and raise the event Changed 
         _customerID = value; 
         if(CustomerIDChanged!=null) 
          CustomerIDChanged(this,value); 
        } 
       } 
      } 
     } 
    } 
} 

在你的表格,當你啓動控制器對象

var controller = new Controller(); 
controller.CustomerIDChanging +=(sd,args) =>{ 
    // here you can test if you want really to change the value or not 
    // in case you want to reject the changes you can apply 
    args.Cancel = true; 
}; 
controller.CustomerIDChanged +=(sd,args) =>{ 

    // here you implement the code **Changed already** 
} 

上面的代碼將讓您對您的代碼有很大的控制,也會讓你的控制器代碼可重複使用和清潔。同樣 結果您可以通過實現INotifyPropertyChanged接口得到

INotifyPropertyChanged的

你可能會對這article看看以獲取更多信息

+0

您可以編輯您的答案並更改拼寫錯誤的方法和事件嗎? – NuWin

+0

您的意思是,我添加了事件名稱和代表作爲示例,您可以按照您想要的方式更改名稱 – Monah

+0

例如,'public event OnCustomerIDChanging CustoerIDChanging;公共事件OnCustomerIDChanged CustoerIDChanged;'我相信它應該是CustomerIDChanging和CustomerIDChanged。對於其中一個代表空洞,其中一個應該是OnCustomerIDChanged,它們都是OnCustomerIDChanging。 – NuWin