커서를 대기 커서로 돌리게 하려면 어떻게 해야 합니까?
대기/사용 중 커서(일반적으로 모래시계)를 사용자에게 표시하여 프로그램이 어떤 작업을 수행하고 있음을 알리려면 어떻게 해야 합니까?
사용할 수 있습니다.
// Set cursor as hourglass
Cursor.Current = Cursors.WaitCursor;
// Execute your time-intensive hashing code here...
// Set cursor as default arrow
Cursor.Current = Cursors.Default;
그러나 해싱 작업이 정말 오래 걸리는 경우(MSDN에서는 이 작업이 2-7초 이상으로 정의됨) 커서 이외의 시각적 피드백 표시기를 사용하여 진행 상황을 사용자에게 알려야 합니다.자세한 지침은 이 문서를 참조하십시오.
편집:
@Am이 지적했듯이, 당신은 아마도 전화를 해야 할 것입니다.Application.DoEvents();
끝나고Cursor.Current = Cursors.WaitCursor;
모래시계가 실제로 표시되는지 확인합니다.
정말로.
Cursor.Current = Cursors.WaitCursor;
일시적으로 대기 커서를 설정하지만 작업이 끝날 때까지 대기 커서가 표시되지 않습니다.실제로 작업이 실행 중인 동안 마우스를 움직일 때처럼 프로그램 내의 다른 프로그램이나 컨트롤이 커서를 기본 화살표로 쉽게 재설정할 수 있습니다.
대기 커서를 표시하는 더 좋은 방법은 양식의 UseWaitCursor 속성을 true로 설정하는 것입니다.
form.UseWaitCursor = true;
이 속성을 false로 설정할 때까지 양식의 모든 컨트롤에 대한 대기 커서가 표시됩니다.애플리케이션 수준에서 대기 커서를 표시하려면 다음을 사용해야 합니다.
Application.UseWaitCursor = true;
이전의 기본 접근 방식(자주 수행되는 작업이기 때문에)은 대기 커서 코드를 ID 일회용 도우미 클래스로 래핑하여 ()(코드 한 줄)을 사용하여 사용할 수 있도록 하고, 선택적 매개 변수를 사용하여 내부에서 코드를 실행한 후 정리(커서 복원)하는 것입니다.
public class CursorWait : IDisposable
{
public CursorWait(bool appStarting = false, bool applicationCursor = false)
{
// Wait
Cursor.Current = appStarting ? Cursors.AppStarting : Cursors.WaitCursor;
if (applicationCursor) Application.UseWaitCursor = true;
}
public void Dispose()
{
// Reset
Cursor.Current = Cursors.Default;
Application.UseWaitCursor = false;
}
}
용도:
using (new CursorWait())
{
// Perform some code that shows cursor
}
양식 또는 창 수준에서 UseWaitCursor를 사용하는 것이 더 쉽습니다.일반적인 사용 사례는 다음과 같습니다.
private void button1_Click(object sender, EventArgs e)
{
try
{
this.Enabled = false;//optional, better target a panel or specific controls
this.UseWaitCursor = true;//from the Form/Window instance
Application.DoEvents();//messages pumped to update controls
//execute a lengthy blocking operation here,
//bla bla ....
}
finally
{
this.Enabled = true;//optional
this.UseWaitCursor = false;
}
}
더 나은 UI 환경을 위해 다른 스레드에서 비동기를 사용해야 합니다.
제 접근법은 모든 계산을 백그라운드 작업자에서 하는 것입니다.
그런 다음 커서를 다음과 같이 변경합니다.
this.Cursor = Cursors.Wait;
스레드 완료 이벤트에서 커서를 복원합니다.
this.Cursor = Cursors.Default;
특정 컨트롤에 대해서도 이 작업을 수행할 수 있으므로 마우스가 컨트롤 위에 있을 때만 커서가 모래시계가 됩니다.
Windows Forms 응용 프로그램의 경우 UI-Control을 선택적으로 비활성화하면 매우 유용할 수 있습니다.그래서 제 제안은 다음과 같습니다.
public class AppWaitCursor : IDisposable
{
private readonly Control _eventControl;
public AppWaitCursor(object eventSender = null)
{
_eventControl = eventSender as Control;
if (_eventControl != null)
_eventControl.Enabled = false;
Application.UseWaitCursor = true;
Application.DoEvents();
}
public void Dispose()
{
if (_eventControl != null)
_eventControl.Enabled = true;
Cursor.Current = Cursors.Default;
Application.UseWaitCursor = false;
}
}
용도:
private void UiControl_Click(object sender, EventArgs e)
{
using (new AppWaitCursor(sender))
{
LongRunningCall();
}
}
그래서 정적 비동기 방식을 만들었습니다.이렇게 하면 작업을 시작하고 응용프로그램 커서를 변경하는 컨트롤이 비활성화됩니다.작업을 태스크로 실행하고 완료될 때까지 기다립니다.제어는 기다리는 동안 호출자에게 돌아갑니다.따라서 사용 중인 아이콘이 회전하는 동안에도 응용 프로그램은 응답성을 유지합니다.
async public static void LengthyOperation(Control control, Action action)
{
try
{
control.Enabled = false;
Application.UseWaitCursor = true;
Task doWork = new Task(() => action(), TaskCreationOptions.LongRunning);
Log.Info("Task Start");
doWork.Start();
Log.Info("Before Await");
await doWork;
Log.Info("After await");
}
finally
{
Log.Info("Finally");
Application.UseWaitCursor = false;
control.Enabled = true;
}
다음은 주 양식의 코드입니다.
private void btnSleep_Click(object sender, EventArgs e)
{
var control = sender as Control;
if (control != null)
{
Log.Info("Launching lengthy operation...");
CursorWait.LengthyOperation(control, () => DummyAction());
Log.Info("...Lengthy operation launched.");
}
}
private void DummyAction()
{
try
{
var _log = NLog.LogManager.GetLogger("TmpLogger");
_log.Info("Action - Sleep");
TimeSpan sleep = new TimeSpan(0, 0, 16);
Thread.Sleep(sleep);
_log.Info("Action - Wakeup");
}
finally
{
}
}
더미 작업(Nlog 사용 중)을 위해 별도의 로거를 사용해야 했고, 메인 로거는 UI(리치 텍스트 상자)에 쓰는 중입니다.양식의 특정 컨테이너 위에서만 사용 중인 커서 쇼를 볼 수 없었습니다. (하지만 열심히 하지는 않았습니다.)모든 컨트롤에 UseWaitCursor 속성이 있지만 시도한 컨트롤에 영향을 미치지 않는 것 같습니다(위에 있지 않아서 그런가요?).
다음은 우리가 예상하는 순서대로 진행되는 상황을 보여주는 메인 로그입니다.
16:51:33.1064 Launching lengthy operation...
16:51:33.1215 Task Start
16:51:33.1215 Before Await
16:51:33.1215 ...Lengthy operation launched.
16:51:49.1276 After await
16:51:49.1537 Finally
좋아요, 다른 사람들의 견해는 매우 분명하지만, 저는 다음과 같이 몇 가지를 추가하고 싶습니다.
Cursor tempCursor = Cursor.Current;
Cursor.Current = Cursors.WaitCursor;
//do Time-consuming Operations
Cursor.Current = tempCursor;
아래 수업을 통해 도넛의 제안을 "예외 안전"으로 만들 수 있습니다.
using (new CursorHandler())
{
// Execute your time-intensive hashing code here...
}
커서 핸들러 클래스
public class CursorHandler
: IDisposable
{
public CursorHandler(Cursor cursor = null)
{
_saved = Cursor.Current;
Cursor.Current = cursor ?? Cursors.WaitCursor;
}
public void Dispose()
{
if (_saved != null)
{
Cursor.Current = _saved;
_saved = null;
}
}
private Cursor _saved;
}
WPF와 함께 사용:
Cursor = Cursors.Wait;
// Your Heavy work here
Cursor = Cursors.Arrow;
사용할 수 있는 항목:
Mouse.OverrideCursor = Cursors.Wait;
&&
Mouse.OverrideCursor = Cursors.Arrow;
언급URL : https://stackoverflow.com/questions/1568557/how-can-i-make-the-cursor-turn-to-the-wait-cursor
'programing' 카테고리의 다른 글
WPF 목록 보기 해제 선택 (0) | 2023.05.29 |
---|---|
Bash를 사용하여 변수 파일을 참조하려면 어떻게 해야 합니까? (0) | 2023.05.29 |
jQuery 처음을 제외한 모든 테이블 행 삭제 (0) | 2023.05.29 |
Objective-C 코코아 응용 프로그램의 정규식 (0) | 2023.05.29 |
MongoDB 데이터베이스 암호화 (0) | 2023.05.29 |