2011-12-19 2 views
3

이상하게 들리 겠지만, 이것은 취미 생활 일뿐입니다. 나는 (사용자 정의) 메시지 상자에 이상적으로 코드를 차단해야하는 YesNo 버튼을 팝업으로 표시하고 싶습니다. 하지만 메시지 상자의 버튼을 특별히 클릭 할 필요없이 메시지 상자를 닫을 수 있도록 상위 폼을 클릭 할 수 있어야합니다. (메시지 상자에서 아니오를 클릭하는 것과 같습니다)모달이 아닌 양식을 만드는 방법은 무엇입니까?

 void Foo() 
    { 
     CustomMsgBox.Show("do you really wanna delete?", CustomMsgBox.Buttons.YesNo); 
     //block the code here, but user should be able to click on form, so that its equivalent to have clicked No; 
     //if clicked No, return; 

     //delete. 
    } 

그래서 내가 생각한 해결책은 사용자 지정 메시지 상자를 모달이 아닌 것입니다. 사용자가 양식을 클릭 할 수 있지만 코드를 차단할 수는 없습니다. 어떻게 할 수 있습니까?

그 결과는 다음과 같습니다

void Foo() 
{ 
    NonModalMsgBox.Show("do you really wanna delete?", CustomMsgBox.Buttons.YesNo); 
    //block thread till user clicks on form or messagebox buttons. 
    //unblock when user clicks. 
    //if No, return; 

    //delete. 
} 

편집 :이 표준 방법이 아닙니다 알고 모달 폼이 할 동안은 차단하지 않는 비 모달 양식을 알고있다. 따라서 모달 양식 또는 모달이 아닌 양식의 동작에 만족할 것을 권장하지 마십시오. 내 질문은 Windows 양식을 사용하여 ContextMenu의 동작을 시뮬레이트하는 방법이있을 것입니다.

+0

재진입 할 ​​가능성이 있기 때문에 불가능합니다. – SLaks

+0

이것이 궁극적으로 불가능하다고 나는 생각하지 않는다. 스레드를 무기한 차단할 수 있지만 주 폼도 고정됩니다. 내 걱정입니다. 더 많은 지식이있는 사람들이 주위에 일을 제공 할 수 있기를 바랍니다. 나는 기본적으로 .net의 다양한 측면을 가지고 놀고 있습니다 .. 어떻게하면 이것이 성취 될 수 있는지 알고 있어야합니다. – nawfal

+1

이것은 Application.DoEvents()를 호출하는 루프가 필요합니다. 그 방법에 위험 요소가 붙어 있습니다. http://stackoverflow.com/questions/5181777/use-of-application-doevents/5183623#5183623 –

답변

0

당신이 뭔가를 할 수 '대화 상자'가 올라간 상태에서 부모 폼의 삭제 버튼을 클릭하면 (첫 번째 대화 상자를 먼저 닫거나 남겨두면 후자가되어 지저분해질 수 있습니다) 원하는 방식입니다.

+0

wil 시도해보십시오 .. – nawfal

+0

Ppl이 말은 나쁜 방법이지만,이 기능이 작동하는 한 내 필요에 따라 코드없이 다른 사람들의 방법을 이해할 수 없다. 나는 이것을 대답으로 표시 할 것이다. 내가 말하고 있던 조건들 중 나머지는 다룰 수있어. 고마워. :) – nawfal

+0

@nawfal 네 질문에 대한 대답이지만, 할 일이 아주 나빴어. 나는 거의 당신이 당신의 프로그램에 문제가있을 것을 보장한다. 당신이 알아 내려고 노력하는 많은 머리카락을 꺼낼 것이다 ... –

2

기본적으로 '차단'통화에서는 쉽게이 작업을 수행 할 수 없습니다. 쉽게 수행 할 수있는 작업은 삭제를 수행하는 데 필요한 정보 나 작업을 수행 할 대리자를 양식에 전달하는 것입니다. 그들이 Ok를 클릭하면 작업을 수행하기 만하면됩니다. 자녀가 부모 양식을 활성화 한 경우 자녀를 닫으십시오.

+0

미안, 나는 네가 의미하는 것을 이해하지 못했다. 작은 코드를 보여줄 수 있습니까? 나는 대리인들과 조금 약하다. – nawfal

1

사용자가 배경 창을 클릭하여 대화 상자를 취소 할 수있게 하시겠습니까? 핸들러를 배경 윈도우에 추가하여 사용자가 클릭 할 때 비 모달 윈도우가 표시되는지 확인합니다. 그렇지 않은 경우 닫습니다.

소리는 간단하지만 배경 창과 자식 창에서 가능한 모든 클릭을 처리 할 때는주의해야합니다. 그건 내가 싫어할 웜의 깡통처럼 들린다.

아마도 모달이 아닌 대화 상자에서 포커스가 사라지고 자동으로 닫히는 지 여부를 감지 할 수 있습니다. 이 동작은 간단한 "확인 삭제"대화 상자에서 의미가 있지만 사용자가 처음 대화 상자를 닫으려면 ESC 키를 스팸으로 보내는 것으로 나타납니다. - 내가 행동 할 여부를 확인 I를 그 것이 얼마나 안정적 확실하지 않다,도 오전

public void ShowMe() { 
    Show(); 
    while (!_receivedDeactivateEvent) 
     Application.DoEvents(); 
} 

내가하지만, 그것을 권하고 싶습니다 확실하지 않다 :

+0

간단하게 들린다. .. 보자. – nawfal

+0

나는이 모든 브라이언을 할 수있다. 그러나 여기의 걱정은 비 모달 폼이 블로킹하지 않기 때문에 코드를 블로킹하지 않는다. 예 아니요. 이것은 내가 기본적으로 찾고있는 것이 아닙니다. – nawfal

+0

모달 대화 상자의 주요 기능은 차단하는 것입니다. 넌 모달 대화 상자의 주요 특징은 넌 블로킹 (non-blocking)이라는 것입니다. 일종의 모순처럼 보이는 넌 모달 대화 상자를 차단하고 싶습니다. 팝업 메뉴는 초점을 잃으면 자동으로 닫히고 설명하는 것과 매우 비슷하게 보입니다. –

3

아주 쉽게 해결할 수 있습니다. 만들고 모달 대화 상자를 사용하여 대화 상자의 WndProc 무시하고 WM_MOUSEDOWN 이벤트를 처리하십시오. 마우스의 위치를 ​​확인하십시오. 부모 창 위에 있지만 대화 상자 자체가 아닌 경우 대화 상자를 닫으십시오.

+0

기본 코드 또는 일부 샘플 코드에 대한 링크를 제공 할 수 있습니까? 나는이 일에 초보자이다. – nawfal

1

ShowDialog를 호출 할 때이 수동으로 부모 폼을 가능하게하는 것입니다 처리하는 또 다른 방법,

[DllImport("user32.dll")] 
private static extern bool EnableWindow(IntPtr hWnd, bool enable); 

internal static DialogResult ShowDialogSpecial(this Form formToBeShown, Form parent) 
{ 
    parent.BeginInvoke(new Action(() => EnableWindow(parent.Handle, true))); 
    formToBeShown.ShowDialog(parent); 

    return formToBeShown.DialogResult; 
} 

from here 그냥 같은 어떤 부모 폼에서 확장 메서드 호출 : 물론

var f = new Form(); 
f.ShowDialogSpecial(this); 
//blocks but parent window will be active. 

당신 하위 양식을 닫으려면 상위 양식의 클릭을 처리해야합니다.

0

쉬운 방법 : 양식의 "TopMost"속성을 True로 설정하십시오. 그러면 차단과 같은 역할을합니다.