2013-05-01 1 views
1

진행률 표시 줄이있는 메인 폼이 있는데 "Logic"이라는 외부 클래스에서 진행률 표시 줄을 업데이트하려고합니다 ... 그러나 Logic은 이미 기본 폼에서 참조되고 있습니다. 진행률 표시 줄을 업데이트하기 위해 Logic의 기본 폼을 참조하려고하면 스택 오버플로가 발생합니다.메인 폼의 진행률 막대를 외부 클래스에서 업데이트 하시겠습니까?

주위를 둘러 보면서 BackgroundWorker에 대해 많은 주제를 접했지만 그게 내가 사용하려고하는 것이 아닙니다. progress bar.PerformStep()을 사용하여 메인 폼의 진행률 막대를 업데이트하려는 Logic 클래스의 특정 위치가 있습니다. 나는 진도 막대를 업데이트하고 Logic 클래스에서 그것을 호출하는 메인 폼에 메소드를 만들려고했으나 다시 한번 참조가 부족하다 ... 그리고 MainForm frm1 = new MainForm()을 사용하지 않고서는 사용할 수 없다. 다른 곳에서는 오류가 발생했습니다. 나는 여기 꽤 난처한 느낌이다.

[편집] 여기

홈페이지 양식 (당신 덕분에 사람) ---- 솔루션과 코드 :

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 

namespace Natural_Language_Processor 
{ 
public partial class frm_Main : Form 

{ 
    Logic logic = new Logic(); 

    public frm_Main() 
    { 
     InitializeComponent(); 
    } 

    private void frm_Main_Load(object sender, EventArgs e) 
    { 
     Timer.Start(); 
    } 

    private void btn_Enter_Click(object sender, EventArgs e) 
    { 
     logic.Progress += new Logic.ProgressDelegate(DisplayProgess); 
     logic.RaiseProgress(0); 

     logic.str_Input = txt_Input.Text; 
     logic.Prep_Input(); 

     txt_Input.Text = ""; 
     logic.RaiseProgress(100); 
     System.Threading.Thread.Sleep(100); 
     logic.RaiseProgress(0); 
    } 

    private void exitToolStripMenuItem_Click(object sender, EventArgs e) 
    { 
     Application.Exit(); 
    } 

    private void eraseToolStripMenuItem_Click(object sender, EventArgs e) 
    { 
     logic.EraseMemory(); 
    } 

    public void DisplayProgess(int percent) 
    { 
     if (this.InvokeRequired) 
     { 
      this.Invoke(new Logic.ProgressDelegate(DisplayProgess), new Object[] { percent }); 
     } 
     else 
     { 
      this.progbar.Value = percent; 
     } 
    } 
} 

논리 :

using System; 
using System.IO; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Data; 
using System.Data.SqlClient; 
using System.Windows.Forms; 

namespace Natural_Language_Processor 
{ 
class Logic 
{ 
    Data oData = new Data(); 
    public List<string> Words = new List<string>(); 

    private System.Threading.Thread T = null; 

    public delegate void ProgressDelegate(int percent); 
    public event ProgressDelegate Progress; 

    #region Variables 
     public string str_Input; 
     public string[] WordArray; 
    #endregion 

    public void RaiseProgress(int percent) 
    { 
     if (Progress != null) 
     { 
      Progress(percent); 
     } 
    } 

    public void Prep_Input() 
    { 
     //Check for Input 
     if (String.IsNullOrEmpty(str_Input)) 
     { 

     } 
     else 
     { 
      //Set everything to lower-case 
      str_Input = str_Input.ToLower(); 
      RaiseProgress(10); 

      //Remove all punctuation 
      if (str_Input.Contains(",")) 
      { 
       while (str_Input.Contains(",")) 
       { 
        int int_index = str_Input.IndexOf(","); 
        str_Input = str_Input.Remove(int_index, 1); 
       } 
      } 
      if (str_Input.EndsWith(".")) 
      { 
       str_Input = str_Input.Trim('.'); 
      } 
      else if (str_Input.EndsWith("?")) 
      { 
       str_Input = str_Input.Trim('?'); 
      } 
      RaiseProgress(20); 

      //Split the sentence into an array of individual words 
      WordArray = str_Input.Split(' '); 
      RaiseProgress(30); 

      //Get current words (and max ID) from the database 
      int max_index = 0; 
      oData.GetWords(); 
      Words.Clear(); 

      if (oData.WordDataSet.Count > 0) 
      { 
       for (int i = 0; i < oData.WordDataSet.Count; i++) 
       { 
        max_index = oData.WordDataSet[i].ID; 
        Words.Add(oData.WordDataSet[i].Word); 
       } 
      } 
      RaiseProgress(40); 

      //Check each word in the sentence 
      for (int i = 0; i < WordArray.Length; i++) 
      { 
       //Update the frequency of an existing word in the database 
       if (Words.Contains(WordArray[i].ToString())) 
       { 
        oData.UpdateWords(WordArray[i].ToString()); 
       } 
       else 
       { 
        //Or add the word 
        max_index = max_index + 1; 
        oData.InsertWordsTable(max_index, WordArray[i].ToString(), 1); 

        //And create its pre/pro word tables 
        oData.NewPreWordTable(WordArray[i].ToString()); 
        oData.NewProWordTable(WordArray[i].ToString()); 
       } 
      } 
      RaiseProgress(50); 

      //Check each word in the sentence after we have possibly created new pre/pro word tables in the previous code 
      for (int i = 1; i < WordArray.Length; i++) 
      { 
       oData.GetPreWords(WordArray[i].ToString()); 
       Words.Clear(); 

       //Get current pre_words from the database 
       for (int a = 0; a < oData.WordDataSet.Count; a++) 
       { 
        Words.Add(oData.WordDataSet[a].Word); 
       } 

       //Update the frequency of an existing word in the database 
       if (Words.Contains(WordArray[i - 1].ToString())) 
       { 
        oData.UpdatePreWords(WordArray[i].ToString(), WordArray[i - 1].ToString()); 
       } 
       else 
       { 
        //Or add the word 
        oData.InsertPreWord(WordArray[i].ToString(), oData.GetPreWordIndex(WordArray[i].ToString()), WordArray[i - 1].ToString(), 1); 
       } 

       if (i == WordArray.Length - 1) 
       { 

       } 
       else 
       { 
        oData.GetProWords(WordArray[i].ToString()); 
        Words.Clear(); 

        //Get current pro_words from the database 
        for (int b = 0; b < oData.WordDataSet.Count; b++) 
        { 
         Words.Add(oData.WordDataSet[b].Word); 
        } 

        //Update the frequency of an existing word in the database 
        if (Words.Contains(WordArray[i + 1].ToString())) 
        { 
         oData.UpdateProWords(WordArray[i].ToString(), WordArray[i + 1].ToString()); 
        } 
        else 
        { 
         //Or add the word 
         oData.InsertProWord(WordArray[i].ToString(), oData.GetProWordIndex(WordArray[i].ToString()), WordArray[i + 1].ToString(), 1); 
        } 
       } 
      } 
      RaiseProgress(60); 
     } 
    } 

    public void Respond() 
    { 
     RaiseProgress(70); 
    } 

    public void EraseMemory() 
    { 
     oData.GetWords(); 
     Words.Clear(); 
     for (int i = 0; i < oData.WordDataSet.Count; i++) 
     { 
      oData.DeletePreTable(oData.WordDataSet[i].Word); 
      oData.DeleteProTable(oData.WordDataSet[i].Word); 
     } 
     oData.DeleteWordsTable(); 
     MessageBox.Show("Memory has been erased."); 
    } 
} 

}

+2

난 당신이 로직 클래스에서 진행률 막대를 업데이트하는 대리자를 사용할 수 있습니다 생각합니다. –

+0

이러한 * 참조를 유지하는 코드의 일부를 표시하고 해당 스택 오버플로 예외를 가져 오는 위치를 확실히 포함하십시오. – Jesse

+1

진행률 표시 줄이있는 백그라운드 작업자 [ProgressBar가있는 배경 작업자] (http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx) – MethodMan

답변

3

여기 로직() 클래스는 직접 양식을 참조하는 대신 사용자 정의 이벤트를 발생과 더불어, 느슨하게 결합 된 접근 방식 :

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     Logic logic = new Logic(); 
     logic.Progress += new Logic.ProgressDelegate(DisplayProgess); 
     logic.Start(); 
    } 

    public void DisplayProgess(string message, int percent) 
    { 
     if (this.InvokeRequired) 
     { 
      this.Invoke(new Logic.ProgressDelegate(DisplayProgess), new Object[] { message, percent }); 
     } 
     else 
     { 
      this.label1.Text = message; 
      this.progressBar1.Value = percent; 
     } 
    } 

} 

public class Logic 
{ 

    private System.Threading.Thread T = null; 

    public delegate void ProgressDelegate(string message, int percent); 
    public event ProgressDelegate Progress; 

    public void Start() 
    { 
     if (T == null) 
     { 
      T = new System.Threading.Thread(new System.Threading.ThreadStart(Worker)); 
      T.Start(); 
     } 
    } 

    private void Worker() 
    { 
     RaiseProgress("Initializing...", 0); 
     System.Threading.Thread.Sleep(1000); // simulated work 

     RaiseProgress("Loading Map...", 25); 
     System.Threading.Thread.Sleep(1500); // simulated work 

     RaiseProgress("Loading Sprites...", 50); 
     System.Threading.Thread.Sleep(1200); // simulated work 

     RaiseProgress("Loading Sound Effects...", 75); 
     System.Threading.Thread.Sleep(1700); 

     RaiseProgress("Loading Music...", 85); 
     System.Threading.Thread.Sleep(1100); // simulated work 

     RaiseProgress("Done!", 100); 
    } 

    private void RaiseProgress(string message, int percent) 
    { 
     if (Progress != null) 
     { 
      Progress(message, percent); 
     } 
    } 

} 
+0

로직 코드의 특정 지점에서 진행률 표시 줄을 만드는 데 사용하는 방법을 모르겠습니다. –

+0

진도 표시 줄에서 실제로 시뮬레이션을 진행하는 것이 아니라 진행률을 나타내기를 원합니다. 그래도 깔끔한 코드. –

+0

예제에서, 메인 폼은 Logic() 인스턴스를 생성하고 Progress() 이벤트에 가입했습니다. Logic()에서 RaiseProgress()를 호출하고 진행 상황을 업데이트해야 할 때마다 메시지와 퍼센트 완료를 전달하면됩니다. 기본 양식은 이벤트를 받고 이에 따라 업데이트됩니다. 물론 나는 progess를 "시뮬레이트"해야했습니다 ... 나는 당신의 앱이 실제로 무엇을하고 있는지 모른다. =) –

관련 문제