development

WPF에서 커서를 변경해도 작동하지 않는 경우가 있습니다.

big-blog 2020. 7. 17. 07:42
반응형

WPF에서 커서를 변경해도 작동하지 않는 경우가 있습니다.


여러 사용자 정의 컨트롤에서 커서를 사용하여 커서를 변경합니다.

this.Cursor = Cursors.Wait;

내가 뭔가를 클릭하면.

이제 버튼 클릭시 WPF 페이지에서 동일한 작업을 수행하려고합니다. 버튼 위로 마우스를 가져 가면 커서가 손 모양으로 바뀌지 만 클릭하면 대기 커서로 바뀌지 않습니다. 이것이 버튼이라는 사실과 관련이 있는지, 또는 이것이 사용자 정의 컨트롤이 아닌 페이지이기 때문에 궁금합니다. 이상한 행동 인 것 같습니다.


특정 페이지 / 사용자 컨트롤 위에있을 때만 커서가 "대기"커서 여야합니까? 그렇지 않은 경우 Mouse.OverrideCursor 사용하는 것이 좋습니다 .

Mouse.OverrideCursor = Cursors.Wait;
try
{
    // do stuff
}
finally
{
    Mouse.OverrideCursor = null;
}

UI의 일부가 아닌 응용 프로그램의 커서를 재정의하므로 설명하는 문제가 사라집니다.


응용 프로그램에서이 작업을 수행하는 한 가지 방법은 IDisposable을 사용한 다음 using(){}블록을 사용하여 커서가 완료되면 다시 설정되도록하는 것입니다.

public class OverrideCursor : IDisposable
{

  public OverrideCursor(Cursor changeToCursor)
  {
    Mouse.OverrideCursor = changeToCursor;
  }

  #region IDisposable Members

  public void Dispose()
  {
    Mouse.OverrideCursor = null;
  }

  #endregion
}

그런 다음 코드에서 :

using (OverrideCursor cursor = new OverrideCursor(Cursors.Wait))
{
  // Do work...
}

다음 중 하나에 해당하면 대체가 종료됩니다. using 문의 끝에 도달하거나; 예외가 발생하고 제어문이 명령문 종료 전에 명령문 블록을 떠나는 경우.

최신 정보

커서가 깜빡이지 않게하려면 다음을 수행하십시오.

public class OverrideCursor : IDisposable
{
  static Stack<Cursor> s_Stack = new Stack<Cursor>();

  public OverrideCursor(Cursor changeToCursor)
  {
    s_Stack.Push(changeToCursor);

    if (Mouse.OverrideCursor != changeToCursor)
      Mouse.OverrideCursor = changeToCursor;
  }

  public void Dispose()
  {
    s_Stack.Pop();

    Cursor cursor = s_Stack.Count > 0 ? s_Stack.Peek() : null;

    if (cursor != Mouse.OverrideCursor)
      Mouse.OverrideCursor = cursor;
  }

}

버튼에서 데이터 트리거 (뷰 모델 사용)를 사용하여 대기 커서를 활성화 할 수 있습니다.

<Button x:Name="NextButton"
        Content="Go"
        Command="{Binding GoCommand }">
    <Button.Style>
         <Style TargetType="{x:Type Button}">
             <Setter Property="Cursor" Value="Arrow"/>
             <Style.Triggers>
                 <DataTrigger Binding="{Binding Path=IsWorking}" Value="True">
                     <Setter Property="Cursor" Value="Wait"/>
                 </DataTrigger>
             </Style.Triggers>
         </Style>
    </Button.Style>
</Button>

뷰 모델의 코드는 다음과 같습니다.

public class MainViewModel : ViewModelBase
{
   // most code removed for this example

   public MainViewModel()
   {
      GoCommand = new DelegateCommand<object>(OnGoCommand, CanGoCommand);
   }

   // flag used by data binding trigger
   private bool _isWorking = false;
   public bool IsWorking
   {
      get { return _isWorking; }
      set
      {
         _isWorking = value;
         OnPropertyChanged("IsWorking");
      }
   }

   // button click event gets processed here
   public ICommand GoCommand { get; private set; }
   private void OnGoCommand(object obj)
   {
      if ( _selectedCustomer != null )
      {
         // wait cursor ON
         IsWorking = true;
         _ds = OrdersManager.LoadToDataSet(_selectedCustomer.ID);
         OnPropertyChanged("GridData");

         // wait cursor off
         IsWorking = false;
      }
   }
}

응용 프로그램이 비동기 기능을 사용하고 마우스 커서를 사용하는 경우 기본 UI 스레드에서만 수행하려고합니다. 이를 위해 앱의 디스패처 스레드를 사용할 수 있습니다.

Application.Current.Dispatcher.Invoke(() =>
{
    // The check is required to prevent cursor flickering
    if (Mouse.OverrideCursor != cursor)
        Mouse.OverrideCursor = cursor;
});

참고 URL : https://stackoverflow.com/questions/307004/changing-the-cursor-in-wpf-sometimes-works-sometimes-doesnt

반응형