将鼠标光标绑定到WPF中的按钮属性

时间:2012-05-08 00:05:41

标签: c# wpf binding

我有一个按钮需要花费很多时间才能完成其功能,而且由于漫长的等待(5秒),应用程序似乎停止了。所以在长期运行函数之前我放Cursor = Cursors.Wait并在函数之后放置Cursor = Cursors.Arrow并且一切正常。

但我认为做这样的事情真是太糟糕了。

这就是为什么我想知道是否可以将光标绑定到按钮的属性,以便在按钮执行其功能时光标会发生变化。

4 个答案:

答案 0 :(得分:1)

为什么不使用后台工作程序来执行长时间运行的功能(可能是生产/消费模式)?在我看来,这是最好的方式。您还可以通过进度条通知用户有关其请求状态的信息。

答案 1 :(得分:1)

好的,六年后。 1.看看async-await构建,它非常简单,你的艰巨任务将在非UI线程中执行。 2.由于您单步执行上一个属性,可以将一些bool属性放入模型中,如actionExecuting,并在任务完成之前/之后设置/取消设置。然后在视图中,您可以将主容器的Cursor属性绑定到actionExecuting。要制作技巧,您需要实现IValueConverter。例如(看一下命名空间):

namespace YourApp.Util.Converters
{
    [ValueConversion(typeof(bool), typeof(Cursor))]
    public class BoolToCursorConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter,
            System.Globalization.CultureInfo culture)
        {
            var val = (bool)value;
            if (val)
                return Cursors.WaitCursor;
            return Cursors.Arrow;
        }

        public object ConvertBack(object value, Type targetType, object parameter,
            System.Globalization.CultureInfo culture)
        {
            throw new NotSupportedException();
        }
    }
}

然后,您需要添加此转换器,以便在Window.Resources或您的资源字典中查看,如:

<Window x:Class="YourApp.MainWindow"
        <!-- other namespaces -->
        xmlns:c="clr-namespace:YourApp.Util.Converters">

<Window.Resources>
        <c:BoolToCursorConverter x:Key="BoolToCursorConverter"></c:BoolToCursorConverter>
    </Window.Resources>

而且你可以像

一样使用它
<Grid Cursor="{Binding actionExecuting, Converter={StaticResource BoolToCursorConverter}}">

答案 2 :(得分:0)

我能想到的最简单的事情是创建一个实现IDisposable的类并在构造函数中更改等待光标,并在Dispose方法中将其还原。这确保了如果在它执行的代码执行时抛出异常,则游标不会卡在等待光标中......

public class WaitCursor : IDisposable
{
    private Cursor m_defaultCursor = null;
    public WaitCursor()
    {
        m_defaultCursor = Cursors.Current;
        Cursors.Current = Cursors.WaitCursor;
        Application.UseWaitCursor = true;
    }

    public void Dispose()
    {
        Cursors.Current = m_defaultCursor;
        Application.UseWaitCursor = false;
    }
}

然后您可以使用语句包装长时间运行的代码...

using (var waitCursor = new WaitCursor())
{
    // some long running code...
}

这种方式让未来的开发人员明白包装的代码可能还需要一段时间

答案 3 :(得分:0)

理论上,您可以在某处创建依赖项属性,以便在按钮状态更改时设置鼠标光标。但是,如果您正在按钮单击处理程序内部进行工作,则不太可能执行任何操作,因为您的UI线程需要调度依赖项对象以进行更新。此外,如果您阻止UI线程,则在任务完成之前,您将看不到按钮在视觉上“未按下”。另外,你如何将它绑定到一个开放的,可能更改的按钮组?这听起来不是一个令人满意的解决方案。

我认为在WPF应用程序中处理此类场景的最佳方法是在后台线程(或线程池)中运行长时间运行的任务,这将在完成后将结果发布回UI线程。当发生这种情况时,同时您可以保持UI完全交互,或者使用等待光标(并明确禁用您的UI),或者使用对话框说“正在进行中,请等待[取消按钮]”你想要取消选项。

在后台线程中执行操作也有助于保持WPF应用程序窗口响应窗口管理操作,如移动/最小化/最大化。