[C#] 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 스레드에서만 수행하고 싶을 것입니다. 이를 위해 앱의 Dispatcher 스레드를 사용할 수 있습니다.

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


답변

다음은 나를 위해 일했습니다.

ForceCursor = true;
Cursor = Cursors.Wait;


답변