2012-04-23 169 views
0

我正在研究c#中的程序,它使用列表框作爲主窗體中的選擇方法。它具有可以編輯列表框中的項目的功能。從其他形式訪問功能

我想編輯項目從一個單獨的專用窗體,所以我做了一個窗體的新實例,但每當我嘗試訪問原始窗體的功能(我已公開),我得到這個錯誤: 錯誤2對象引用需要非靜態字段,方法或屬性

我周圍不少看了互聯網上,但我看到的是人們談論使用我的功能的靜態屬性。然而,當我這樣做,我得到更多的上述錯誤的功能

這裏內突然出現了變量等在Form1中的功能(這我試圖引用)

public void ReadConfig(string configFile) 
    { 
     fileList.Clear(); 
     listBoxName.Items.Clear(); 
     FileStream file = null; 

     if (!File.Exists(file)) 
     { 
      MessageBox.Show(file + " was not found: Creating blank file"); 
      using (file = File.Create(file)) ; 
     } 
     else 
     { 
      string line; 
      int lineNumber = 1; 

      // I cut out some long code here where the program reads from a file and saves it to an object 
     } 
    } 

這裏有一個在誤差發生的代碼段(我剪了一些代碼,我將它保存到一個文本文件,但這是關注的主要部分是Form1.ReadFile(Form1.file)

 private void buttonSave_Click(object sender, EventArgs e) 
    { 
     string[] temp = File.ReadAllLines(Form1.file); 
     string[] newFile; 

     if (itemNew == true) 
     { 
      newFile = new string[temp.Length + 1]; 
     } 
     else 
     { 
      newFile = new string[temp.Length]; 
     } 

     for (int i = 0; i < temp.Length; i++) 
     { 
      newFile[i] = temp[i]; 
     } 
     File.WriteAllLines(Form1.file, newFile); 
     ConfigForm.ReadFile(Form1.file); 


     this.Close(); 
    } 

我希望這就夠了我的程序很長,所以我儘量保持它和p一樣簡短直接ossible。感謝您的耐心與我=]

我在編程很新,所以如果任何一種靈魂發生,以幫助你能保持儘可能簡單?

Thanks much =]

+0

什麼編程語言? – JohnFx 2012-04-23 18:49:12

+0

C#。對不起,忘了=] – 2012-04-23 19:03:05

+1

好吧。現在顯示你的代碼,你在哪裏得到錯誤。我們無法通過互聯網閱讀您的屏幕。 – JohnFx 2012-04-23 19:05:00

回答

1

這可能是因爲你試圖使用從第二個你的第一個窗口存在,就好像它們是靜態函數,但事實並非如此。

您可以嘗試解決這個問題是這樣的:

  • 第二形式

    帶班的第一種形式創建一個屬性,如:

    class Form1 : Form 
    { 
        //this property will store reference to the first form 
        public Form1 AssociatedFirstForm { get; set; } 
        //... 
    } 
    
  • 然後在在您創建第二個表單的代碼中,將第一個表單分配給此屬性,該表單可能如下所示(如果您從第一個表單創建第二個表單):

    ... 
    Form2 secondForm = new Form2(); 
    secondForm.AssociatedFirstForm = this; 
    ... 
    

或像這樣(如果你創建的代碼另一部分兩種形式):

... 
    Form1 firstForm = new Form1(); 
    Form2 secondForm = new Form2(); 
    secondForm.AssociatedFirstForm = firstForm; 
    ... 
  • 然後,在你的第二形式,你應該能夠調用從這樣的第一種形式的方法:

    ... 
    var myResultFromAnotherWindow = this.AssociatedFirstForm.SampleMethodToCall(); 
    ... 
    

我想你還應該閱讀更多關於使用static classes and class memberscreating instances of objects。它應該告訴你如何以及何時使用它們。

更新

我沒有寫得很清楚,但是你應該避免設定公開的方法或屬性爲public,如果它不是真的需要。

如果您想要在您的應用程序中創建好的代碼結構並瞭解它應該如何完成,請查找一些關於面向對象編程的文章。

一些示例鏈接:

知道事件機制也可以是有用:http://msdn.microsoft.com/en-us/library/awbftdfh.aspx

+0

所以,我意識到這是一個初學者,但整個「保持一個參考到mainform並使所有的方法公開「是一種反模式,如果我見過。一個更好的解決方案是使用事件向父表單發信號通知事件發生,從而根據需要更新其狀態。我目前寫下的這段文字無法讓人滿意。 – 2012-04-23 19:32:05

+0

我試過這個,但現在我得到了一個不同的錯誤。這一次,它是 錯誤該項目在「資源」參數中指定了多次。 「資源」參數不支持重複的項目。 \t 我把相關的類放在最上面,只是在 上公共部分類Form2:表格 我不確定這是否是正確的地方,但它已經擺脫了原來的錯誤。非常感謝迄今爲止的幫助=] – 2012-04-23 19:39:39

+0

@Ed S .:我沒有告訴讓所有的方法公開,因爲正如你已經說過的那樣,它會違反面向對象的編程概念。但是,如果一個方法(或屬性)是一種特殊的形式,它可以公開它,所以另一種形式(即它的父形式)可以使用它(例如從'OpenFileDialog'形式讀取'FileName')。也許我應該寫信不要在答案中暴露公衆成員。 – 2012-04-23 19:55:39

0

您正在調用類型方法而不是類型實例。當方法沒有被聲明爲靜態時,你需要首先實例化包含這些方法的對象(使用新的)。

0

這是你想要實現的基本想法。更高級的做法是使用代表/事件處理程序,但現在想保持簡單。

表1種

public Form1() 
    { 
     InitializeComponent(); 
    } 

    List<string> _items = new List<string>(); 

    public void LoadListBoxWithItems() 
    { 
     for (int i = 0; i < 5; i++) 
     { 
      _items.Add(string.Format("My New Item {0}", i)); 
     } 
     lbItems.DataSource = _items; 
     lbItems.Refresh(); 
    } 

    private void btnUpdate_Click(object sender, EventArgs e) 
    { 
      Form2 form2 = new Form2(); 
      form2.LoadValues(lbItems.SelectedItem.ToString(), this); 
      form2.ShowDialog(); 
    } 

    public string GetCurrentItem() 
    { 
     return lbItems.SelectedItem.ToString(); 
    } 

    public void UpdateItem(string item, string newitem) 
    { 
     int index = _items.IndexOf(item); 
     _items[index] = newitem; 
     lbItems.Refresh(); 
    } 

表2

public Form2() 
    { 
     InitializeComponent(); 
    } 

    private string _originalvalue = null; 
    private Form1 _form1; 

    public void LoadValues(string item, Form1 form) 
    { 
     _originalvalue = item; 
     _form1 = form; 
    } 


    private void btnSave_Click(object sender, EventArgs e) 
    { 
     // Do work to change value 
     string newvalue = _originalvalue; 
     _form1.UpdateItem(newvalue, _originalvalue); 
    } 
+0

爲什麼在示例代碼中使用xml註釋?尤其是他們沒有完成。 – 2012-04-23 21:33:01

+0

@Peri這是一種習慣。我的大部分代碼都被其他人使用,並且我遵循一定的流程。 1.編寫方法 - 一旦我認爲完成 - 我添加xml註釋部分並摺疊。 2.編寫代碼/重構/等所有測試。一旦所有的測試都通過了 - 我會回過頭來填寫評論/任何額外的注意事項,在辦理入住手續之前。 – tsells 2012-04-24 01:41:13