ShowDialog로 호출되던 폼을 Show로 바꾸면서 화면비표시를 하고싶다.
프로젝트는 C#으로 이루어져 있으며, VB6.0과 연동되어 실행되고 있었다.
구성은 아래와 같다.
문제는 해당폼이 Modal 기동된다는 점이다. |
Modal로 띄워놓고, 화면은 보여주면 안된다. |
이것을 어떻게 해결할것인가… |
나는 이번 수정을 두가지 방법으로 생각해보았다. |
1. 해당폼을 생성하지않고, Load / Shown 이벤트의 내용을 그대로 메소드1에서 수행한다. |
2. 해당폼을 보여주지않도록 수정하고, 그냥 진행한다. |
일단, 비동기 형식으로 접근을 생각해보았다.
솔류션을 새로생성하고,폼을 두개가 되도록 배치한다.
그리고, 폼1은 다음과같이 디자인하였다.
결국 버튼2만 사용하여 해결하였지만,
여기서 중요한것은 폼의 객체는 생성하지만, 유져에게 보여주어서는 안된다는점.
그리고 Load / Shown 이벤트는 그대로 진행되어야 한다는점.
두가지의 미션이 가장 중요한 부분이다.
해당 이벤트가 불리어지는지는 어떻게 확인할까?
아래와 같이 확인해보았다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | using System; using System.Windows.Forms; namespace ApcEventControl { public partial class Form2 : Form { public Form2() { InitializeComponent(); } private void Form2_Load(object sender, EventArgs e) { MessageBox.Show("Form2_Load"); } private void Form2_FormClosing(object sender, FormClosingEventArgs e) { MessageBox.Show("Form2_FormClosing"); } private void Form2_Shown(object sender, EventArgs e) { MessageBox.Show("Form2_Shown"); } private void Form2_FormClosed(object sender, FormClosedEventArgs e) { MessageBox.Show("Form2_FormClosed"); } } } | cs |
폼2에 각각의 이벤트를 생성해서, 메세지박스로 표시
가장 단순하면서, 가장 알아보기 쉬운방법이다.
뭐, 로그로 표현할수도 있었지만, 이번에는 그냥 메세지박스로 표시하기로 한다.
폼1은 아래와같이 구현하였다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | using System; using System.Threading.Tasks; using System.Windows.Forms; namespace ApcEventControl { public partial class Form1 : Form { Form2 fm2; public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { fm2 = new Form2(); fm2.WindowState = FormWindowState.Minimized; fm2.ShowDialog(); fm2.ShowInTaskbar = false; fm2.Hide(); } private int XXX() { fm2 = new Form2(); fm2.FormClosed += Fm2_FormClosed; fm2.WindowState = FormWindowState.Minimized; fm2.ShowInTaskbar = false; fm2.Show(); var task = Task.Run(() => { while (fm2 != null) { System.Threading.Thread.Sleep(100); } string a = ""; MessageBox.Show("1"); MessageBox.Show("2"); MessageBox.Show("3"); if (a == string.Empty) { return 0; } else { return 1; } }); return 9; } private void button2_Click(object sender, EventArgs e) { MessageBox.Show(XXX().ToString()); } private void Fm2_FormClosed(object sender, FormClosedEventArgs e) { fm2 = null; } private void button3_Click(object sender, EventArgs e) { fm2 = new Form2(); fm2.WindowState = FormWindowState.Minimized; fm2.Hide(); fm2.ShowInTaskbar = false; fm2.Show(); MessageBox.Show("1"); MessageBox.Show("2"); MessageBox.Show("3"); } private void button4_Click(object sender, EventArgs e) { fm2.Close(); } } } | cs |
버튼2에서의 처리프로세스
즉, XXX 라고 지칭해둔 함수를 통한 작업이 수행된다.
여기서 중요한것은 Form2 의 인스턴스를 Form1에 private 선언해두고, 해당 인스턴스를 감시한다는점이다.
1 2 | fm2 = new Form2(); fm2.FormClosed += Fm2_FormClosed; | cs |
1 2 3 4 | private void Fm2_FormClosed(object sender, FormClosedEventArgs e) { fm2 = null; } | cs |
내부처리는 위와같다.
form2의 private 객체를 null로 변환한다.
XXX 메소드에서 Task 를 발행해서, 해당객체가 null이 될때까지 감시하도록 하였으니,
이 객체값으로 null이 지정되는 순간, 해당 루프처리까지 탈출하면서 후반부의 처리가 가능하다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | var task = Task.Run(() => { while (fm2 != null) { System.Threading.Thread.Sleep(100); } string a = ""; MessageBox.Show("1"); MessageBox.Show("2"); MessageBox.Show("3"); if (a == string.Empty) { return 0; } else { return 1; } }); | cs |
위의소스에서 while 부분이 탈출된다는점이다.
그리고 메세지박스로 1, 메세지박스로 2, 메세지박스로 3 이 순서대로 출력되고,
마지막으로 리턴값이 0으로 돌아오게된다.
버튼4에서 fm2 를 종료하는 처리를 하게해 두었으니, 실행순서는 아래와같이 되겠다.
1. 샘플 프로그램을 실행한다.
2. 버튼2를 클릭한다.
Form2_Load가 출력
Form2_Shown가 출력
9가출력 <- Task.Run의 결과는 돌아오지 않았으므로, 후속처리는 그대로 실행되었기에 9가 돌아온다.
그리고, 여기서 버튼4를 누른순간, 아래와 같은 결과가 출력된다.
Form2_FormClosing가 출력
Form2_FormClosed가 출력
1 이 출력
2 가 출력
3 이 출력
- 끝 -
위의 소스를 이용해서 ShowDialog 로 되어있던 폼을 Show 로 불러오면서, 해당결과를 그대로 얻기위한 방법을 연구해보았다.
혹시나 같은 문제에 봉착한 사람들이 있다면, 조그마한 도움이라도 되고자 이 글을 남겨둔다.
소스는 아래의 링크를 참고하세요.
https://github.com/sungmanko/ApcEventControl
'C#' 카테고리의 다른 글
Drag and Drop 으로 파일을(PDF) 프리뷰 하기 (0) | 2020.01.06 |
---|---|
C# TabControl TabPage안의 TextBox 생성 (0) | 2019.03.15 |
비동기처리에 대한 이해와 설명 (0) | 2019.02.20 |
C#으로 Sound Control 제어하기 (사운드믹서) (0) | 2018.12.03 |
서로다른 두개의폼의 값 제어하기 (0) | 2018.10.09 |