C# 在 WPF 中更改光标有时有效,有时无效
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/307004/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Changing the cursor in WPF sometimes works, sometimes doesn't
提问by ScottG
On several of my usercontrols, I change the cursor by using
在我的几个用户控件上,我通过使用更改光标
this.Cursor = Cursors.Wait;
when I click on something.
当我点击某物时。
Now I want to do the same thing on a WPF page on a button click. When I hover over my button, the cursor changes to a hand, but when I click it, it doesn't change to the wait cursor. I wonder if this has something to do with the fact that it's a button, or because this is a page and not a usercontrol? This seems like weird behavior.
现在我想通过单击按钮在 WPF 页面上做同样的事情。当我将鼠标悬停在按钮上时,光标会变为手形,但是当我单击它时,它不会变为等待光标。我想知道这是否与它是一个按钮有关,还是因为这是一个页面而不是用户控件?这似乎是一种奇怪的行为。
采纳答案by Matt Hamilton
Do you need the cursor to be a "wait" cursor only when it's over that particular page/usercontrol? If not, I'd suggest using Mouse.OverrideCursor:
只有当光标位于该特定页面/用户控件上时,您才需要光标是“等待”光标吗?如果没有,我建议使用Mouse.OverrideCursor:
Mouse.OverrideCursor = Cursors.Wait;
try
{
// do stuff
}
finally
{
Mouse.OverrideCursor = null;
}
This overrides the cursor for your application rather than just for a part of its UI, so the problem you're describing goes away.
这将覆盖您的应用程序的光标,而不仅仅是其 UI 的一部分,因此您所描述的问题就消失了。
回答by Dennis
One way we do this in our application is using IDisposable and then with using(){}
blocks to ensure the cursor is reset when done.
我们在我们的应用程序中这样做的一种方法是使用 IDisposable 然后使用using(){}
块来确保完成后光标被重置。
public class OverrideCursor : IDisposable
{
public OverrideCursor(Cursor changeToCursor)
{
Mouse.OverrideCursor = changeToCursor;
}
#region IDisposable Members
public void Dispose()
{
Mouse.OverrideCursor = null;
}
#endregion
}
and then in your code:
然后在你的代码中:
using (OverrideCursor cursor = new OverrideCursor(Cursors.Wait))
{
// Do work...
}
The override will end when either: the end of the using statement is reached or; if an exception is thrown and control leaves the statement block before the end of the statement.
覆盖将在以下任一情况下结束:到达 using 语句的结尾或;如果抛出异常并且控制在语句结束之前离开语句块。
Update
更新
To prevent the cursor flickering you can do:
为了防止光标闪烁,您可以执行以下操作:
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;
}
}
回答by Zamboni
You can use a data trigger (with a view model) on the button to enable a wait 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>
Here is the code from the view-model:
这是视图模型中的代码:
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;
}
}
}
回答by Valeriu Caraulean
If your application uses async stuff and you're fiddling with Mouse's cursor, you probably want to do it only in main UI thread. You can use app's Dispatcher thread for that:
如果您的应用程序使用异步内容并且您正在摆弄鼠标的光标,则您可能只想在主 UI 线程中执行此操作。您可以使用应用程序的 Dispatcher 线程:
Application.Current.Dispatcher.Invoke(() =>
{
// The check is required to prevent cursor flickering
if (Mouse.OverrideCursor != cursor)
Mouse.OverrideCursor = cursor;
});
回答by Mike Lowery
The following worked for me:
以下对我有用:
ForceCursor = true;
Cursor = Cursors.Wait;