2

我有一个应用程序在单击按钮时会进行一些非常复杂的计算。我仍在努力提高此代码的效率,但与此同时,我想通过更新 UI 上的标签向用户提供反馈,以显示该按钮已被单击并且计算正在进行中。

在点击事件完成之前,UI 不会更新,因此我必须将代码放入一个事件中,该事件在触发点击事件的代码之前被调用。

到目前为止,我正在使用在PreviewMouseLeftButtonDown执行 click 事件之前调用的事件来更新标签。这适用于鼠标单击。
但是,如果用户在按钮处于焦点时按 Enter 键,则似乎从未触发PreviewKeyDownANDKeyDown事件,或者至少在触发 Click 事件之前未触发。

当按下回车键时,我可以使用什么事件来更新标签,或者您知道在运行 Click Event 的代码之前我可以让标签更新的另一种方法吗?

更新:我注意到PreviewKeyDown事件是在事件之前触发的,但是在事件代码运行click之前我没有看到标签更新。click我看不出我的代码有什么问题。

    private void Button1_KeyDown(object sender, KeyEventArgs e)
    {
        try
        {
            if (e.Key == Key.Return || e.Key == Key.Enter)
            {
                lblMessage.Content = "Loading...";
            }
        }
        catch (Exception)
        {

        }
    }
4

3 回答 3

1

我理解您的困境,我听起来好像您正在将您的用户界面线程与业务逻辑捆绑在一起。更有效的解决方案是创建一个新线程并在那里运行您的计算。您创建计算类,订阅执行代码中的完成事件并启动线程。这样,您可以在执行期间的任何时候设置标签,因为您的业务逻辑在与用户界面不同的线程上运行。

于 2012-11-02T13:31:45.623 回答
0

为什么不使用按钮的命令属性而不是事件?

该命令由鼠标点击或回车键触发。

指挥概述

命令绑定

xml:

 <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Button Grid.Row="0" Command="{Binding CalculationCommand}" Content=" Calculate" />
        <Label Grid.Row="1" Content="{Binding StateText}" />
    </Grid>

视图模型:

public class ViewModel : INotifyPropertyChanged
{
    private string _stateText;

    public RelayCommand CalculationCommand { get; set; }

    public string StateText
    {
        get { return _stateText; }
        set { _stateText = value;  OnPropertyChanged("StateText");}
    }

    public ViewModel()
    {
        CalculationCommand = new RelayCommand(OnCalculate);
        StateText = string.Empty;
    }

    private void OnCalculate(object obj)
    {
        StateText = "Please wait, calculating.";

        var context = TaskScheduler.Current;

        Task.Factory.StartNew(() =>{
                                        //Calculating Logic goes here   
                                   }).ContinueWith(x =>
                                                       {
                                                           StateText = "Done.";
                                                       },context);


    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

我正在使用 Josh Smith文章中的 RelayCommand

于 2012-11-02T13:25:08.403 回答
0

您可以尝试使用.Refresh()来强制标签在编辑后更新。然后您无需担心绑定不同的事件 - 只需更改您需要的任何内容,调用.Refresh(),然后开始主要处理。

于 2012-11-02T13:28:12.860 回答