2013-03-22 79 views
0

我正在編寫一個小程序,該程序應該處理CSV和XML之間的轉換以及從XML到TXT的轉換。在主窗體中,我插入了兩個單選按鈕,用戶將單擊該按鈕開始所需的轉換。從另一個表格參考RadioButton_Checkedchanged值

到目前爲止,我必須使用.cs文件:MainForm.cs和ConversionForm.cs。

在MainForm.cs中,我已經聲明MainForm爲靜態,爲ConversionForm提供對其方法的訪問。

public MainForm() 
    { 
     InitializeComponent(); 
    } 

    public static MainForm mform = null; 

...然後我插入事件處理程序,檢查更改的功能:

public void CSVConversionRadio_CheckedChanged(object sender, EventArgs e) 
    { 
     this.CSVConversionRadio.Checked = true; 
    } 

    public void TXTConversionRadio_CheckedChanged(object sender, EventArgs e) 
    { 
     this.TXTConversionRadio.Checked = true; 
    } 

我有一個「轉換」按鈕應該處理...

在ConversionForm該轉換基於用戶的輸入選擇。

public void conversionButton_Click(object sender, EventArgs e) 
    { 

     if (MainForm.mform.CSVConversionRadio.Checked = true) 
     { 
      CSVConversion(); 
     } 

     if (MainForm.mform.TXTConversionRadio.Checked = true) 
     { 
      TXTConversion(); 
     } 
    } 

我面臨的問題是,當函數檢查單選按鈕的狀態,程序返回「空」,拋出異常。做一些修改代碼,也就是聲明靜態函數

public static MainForm mform = null;之前

MainForm.mform.CSVConversionRadio.Checked總返回「假」,原因可能是一種新形式(轉化率)狀態被實例化並且事件處理程序將其狀態重置爲默認狀態。

所以,這裏是我的問題:

  1. 我怎樣才能單選按鈕的當前值傳遞給轉換表格,允許轉換功能根據用戶的選擇執行?

  2. 一般來說,我如何從另一個表單引用屬性,方法和字段,而不創建新的實例,但只指向前一個仍然打開?

+0

我編輯了你的標題。請參閱:「[應該在其標題中包含」標籤「](http://meta.stackexchange.com/questions/19190/)」,其中的共識是「不,他們不應該」。 – 2013-03-22 21:46:09

+1

我不認爲你需要在CheckChanged事件中再次設置複選框的值。試着評論一下,看看會發生什麼。 – 2013-03-22 21:46:30

+1

另外,你不是指'if(MainForm.mform.CSVConversionRadio.Checked = true)'。你的意思是'if(MainForm.mform.CSVConversionRadio.Checked == true)',它與'if(MainForm.mform.CSVConversionRadio.Checked)'相同' – 2013-03-22 21:47:11

回答

0

扔掉那個靜態變量mform。如果您以空值離開,沒用。
相反,當你調用ConversionForm從MainForm的構造函數的MainForm的實例傳遞給ConversionForm實例

ConversionForm conv = new ConversionForm(this); 

然後在ConversionForm的構造保存在一個全局變量

public partical class ConversionForm:Form 
{ 
    MainForm _currentInstanceMainForm = null 
    public ConversionFomr(MainForm f) 
    { 
     _currentInstanceMainForm = f; 
    } 
} 

通過實例現在當您需要調用MainForm的公共方法時,您可以使用通過建造時的實例

public void conversionButton_Click(object sender, EventArgs e) 
{ 
    if (_currentInstanceMainForm.CSVConversionRadio.Checked == true) 
    { 
     CSVConversion(); 
    } 

    if (currentInstanceMainForm.TXTConversionRadio.Checked == true) 
    { 
     TXTConversion(); 
    } 
} 

但是,最好隔離MainForm的內部控件,並且絕對不要讓外部窗體直接訪問MainForm的控件。
爲了讓這個模式,你需要準備每一個外在形式可以檢查得到MainForm的狀態信息的兩個公共屬性控制

在MainForm中添加這兩個公共屬性

public bool CSVConversionRequired 
{ 
    get { return (this.CSVConversionRadio.Checked); } 
} 

public bool TXTConversionRequired 
{ 
    get { return (this.TXTConversionRadio.Checked); } 
} 

,改變ConversionForm到

public void conversionButton_Click(object sender, EventArgs e) 
{ 
    if (_currentInstanceMainForm.CSVConversionRequired == true) 
     CSVConversion(); 

    if (currentInstanceMainForm.TXTConversionRequired == true) 
    { 
     TXTConversion(); 
    } 
} 
+1

我冒險添加獲取屬性的訪問器。 – Patrick 2013-03-22 23:33:47

+0

哎呀,這確實是一個信號。是時候打開袋子了。感謝Patrick。 – Steve 2013-03-22 23:40:57

+0

謝謝史蒂夫。但是,經過一番審判,我無法解決這個問題。完全按照您的建議進行編碼,可以爲某些元素提供一些空例外。例如,如果(_currentInstanceMainForm.CSVConversionRequired == true) CSVConversion(); 編譯器向我返回一個空異常,可能是因爲:MainForm _currentInstanceMainForm = null。 – user1776401 2013-03-25 18:59:56

0

在表單之間共享信息有幾種方式。

我認爲對你來說一個簡單的方法是有一箇中介類,這兩種形式都知道。

public class ConversionContext : INotifyPropertyChanged { 
    private ConversionType type; 

    public ConversionType Type { 
     get { return type; } 
     set { 
      if (type != value) { 
       type = value; 
       onPropertyChanged("ConversionType"); 
      } 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    private void onPropertyChanged(string propertyName) { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) { 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

public enum ConversionType { None, Xls, Csv, Txt } 

然後,當你創建你的表格,你通過同一ConversionContext的實例給他們,使用一個構造函數或兩種形式的屬性。如果你使用的是財產,這是如何完成的。

private ConversionContext context; 
public ConversionContext SharedContext { 
   get { return context; } 
   set { 
       if (context == value) { 
          return; 
         } 
         if (context != null) { 
           context.PropertyChanged -= onContextPropertyChanged; 
         } 
         context = value; 
         context.PropertyChanged += onContextPropertyChanged; 
   } 
} 

在您的主窗體中,您可以爲用戶檢查設置此類型的控件添加事件處理程序。

public void CSVConversionRadio_CheckedChanged(object sender, EventArgs e) 
{ 
    context.Type = ConversionType.Csv; 
} 

設置類型時,會觸發PropertyChanged事件,您可以在窗體中選擇並響應。

private void onContextPropertyChanged(object sender, PropertyChangedEventArgs e) { 
    switch (context.Type) { 
     case ConversionType.Xls : 
       // check a checkbox that represents xls 
     break; 
     // handle the other file types 
    } 
} 

而在你ConversionForm按下按鈕時,該類型設置

public void conversionButton_Click(object sender, EventArgs e) { 
    switch (context.Type) { 
     case ConversionType.Csv: 
      CSVConversion(); 
      break; 
     case ConversionType.Txt: 
      TXTConversion(); 
      break; 
    } 
} 

這也降低了形式之間的依賴關係,導致looser coupling兩者之間。

+0

Patrick,謝謝。另外,史蒂夫,感謝您的解決方案。帕特里克,老實說,我認爲你的解決方案對我來說太複雜了。我嘗試過,但我得到例外的例外。我需要一個簡單的,就像史蒂夫的那個,也是給我錯誤。 – user1776401 2013-03-22 23:00:38

+0

您遇到什麼異常? – Patrick 2013-03-22 23:19:00

+0

Steve,在您的解決方案中,我使用它得到了一個錯誤。這裏ConversionForm conv = new ConversionForm(this);我在這裏得到2個錯誤。返回(this.TXTConversionRadio.Checked); vstudio exxts一套或獲得訪問者...我想我會爲covnersion創建兩個表格形式... – user1776401 2013-03-22 23:20:44