处理请求时禁用按钮

Posted

技术标签:

【中文标题】处理请求时禁用按钮【英文标题】:Disable button while processing request 【发布时间】:2012-03-12 14:02:27 【问题描述】:

我是 wpf 和 xaml(一般是 Windows 开发)的新手,我的背景是 asp.net,并且在那个经典的 ASP 之前。

我正在开发一个应用程序,该应用程序需要在处理过程中禁用/灰显按钮,并阅读此处的帖子以执行以下操作,但它似乎无法正常工作。我错过了什么?

<Window x:Class="SCGen.Application.LoadForecast.EngineExecution"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:igEditors="http://infragistics.com/Editors"        
    SizeToContent="WidthAndHeight"
    Title="Engine Execution"
    ResizeMode="NoResize"
    WindowStartupLocation="CenterOwner"
    Background="StaticResource x:Static SystemColors.ControlBrushKey">
<Window.Resources>
    <Style TargetType="x:Type Button" x:Key="myStyle" BasedOn="StaticResource ButtonStyle">
        <Setter Property="Command" Value="Binding ExecuteEngine" />
        <Setter Property="Content" Value="Execute Engine" />
        <Style.Triggers>
            <Trigger Property="Command" Value="x:Null">
                <Setter Property="IsEnabled" Value="False"/>
            </Trigger>
        </Style.Triggers>
    </Style>
</Window.Resources>    
<Border Padding="8">
    <StackPanel>
        <StackPanel MaxWidth="200" HorizontalAlignment="Left">
            <TextBlock Text="Select Forecast Engine" TextAlignment="Center" FontSize="13" />

            <igEditors:XamComboEditor ItemsSource="Binding ForecastEngines" SelectedItem="Binding SelectedEngine" Margin="0,5" />

            <Button Style="StaticResource ResourceKey=myStyle" />
        </StackPanel>

        <TextBlock Text="Binding EngineStatus" FontSize="15" FontStyle="Italic" Margin="0,14" Width="400" TextWrapping="Wrap" />
    </StackPanel>
</Border>

</Window>

我已将 xaml 更改为以下内容:

<Button Content="Execute Weather Import" Command="Binding ExecuteWeather" Style="StaticResource ButtonStyle" IsEnabled="Binding IsEnabled"/>

在 ViewModel 我有以下内容:

private bool _isEnabled = true;
    public bool IsEnabled
     
        get  return _isEnabled; 
        set  _isEnabled = value; 
    

我在这里设置了_isEnabled:

private string LaunchWeatherImport(string strVendor)
    
        _isEnabled = false;

        string uri = ConfigurationManager.AppSettings["ManualExecutionFacilitatorService"];
        ClientConnectionInfo connection = new ClientConnectionInfo(uri)  UseSecurity = true ;
        connection.SetTimeouts();

        Logger.LogInfo("Calling Facilitator service to manually import " + strVendor + " weather data.");

        ((NetTcpBinding)connection.Binding).Security.Mode = System.ServiceModel.SecurityMode.None;

        using (var client = new FacilitatorManualExecutionClient(connection))
        
            client.InnerChannel.OperationTimeout = TimeSpan.FromMinutes(int.Parse(ConfigurationManager.AppSettings["OperationTimeOutMinutes"]));

            try
            
                _isEnabled = true;
                return "success";
                // uncomment this line before commit
                //return client.ExecuteWeather(strVendor);
            
            #region catch
            catch (Exception ex)
            
                Logger.LogError(ex.Message, ex);
                return ex.Message;
            
            #endregion
        
    

我仍然无法让它正常工作。

【问题讨论】:

我想问题已经得到解答,但我想指出的是,在使用命令时,您可以使用 CanExecute 方法来禁用与特定命令关联的控件。如果有兴趣,您可以阅读msdn 上的一些信息。 【参考方案1】:

对于初学者,您在 Command 属性上设置了触发器,但您没有在该属性上为您的按钮设置绑定:

<Button Style="StaticResource ResourceKey=myStyle" />

应该是:

<Button Style="StaticResource ResourceKey=myStyle" Command="Binding MyCommand" />

[其中 MyCommand 是您要绑定的实际命令的名称]

我不太确定它是否会起作用,因为当 Command 属性为空时,您的触发器被设置为触发,但是如果您按照 MVVM 模式绑定到命令属性,那么您的命令属性不应该为空所以触发器也不会触发。

更新:

您需要在具有该属性的类上实现INotifyPropertyChanged 接口。

public class MyClass : System.ComponentModel.INotifyPropertyChanged

然后添加实现:

public event PropertyChangedEventHandler PropertyChanged;

private void NotifyPropertyChanged(String info)

    if (PropertyChanged != null)
    
        PropertyChanged(this, new PropertyChangedEventArgs(info));
    

然后将您的属性更改为:

private bool _isEnabled = true;
public bool IsEnabled
 
    get  return _isEnabled; 
    set 
     
       _isEnabled = value;
       NotifyPropertyChanged("IsEnabled");
    

【讨论】:

您好,感谢您的回复。我将按钮标签更改为您上面提到的方式,但仍然没有骰子。这个应用程序确实遵循 MVVM,在此之前我没有使用过 MVVM、WPF 或 Xaml。触发器应该使用什么而不是 x:Null 来使其正常工作? 我假设您的代码来自:***.com/questions/4138026/…?如果是这种情况,那么您应该注意他们的示例有效,因为他们的 Command 接口正在使用 CanExecute 函数。所以当命令可以执行时,命令返回绑定,否则为空。这就是为什么它在他们的示例中有效。实现此目的的另一种方法是在 ViewModel 中创建一个支持 IsButtonEnabled 属性并将按钮的 IsEnabled 属性绑定到此属性。 是的,我做到了,无论是那个帖子还是另一个类似的帖子。我实际上在视图模型中创建了一个属性: private bool _isEnabled = true;公共布尔 IsEnabled 获取 返回 _isEnabled; 设置 _isEnabled = 值;在 xaml 中: 我将属性设置为 false 时代码执行并在执行后返回true,但仍然没有骰子。 您需要在您的类中实现INotifyPropertyChanged接口,该接口具有该属性,然后在设置后调用您的属性中的通知函数。这将使您的 UI 知道该属性已更改,因此需要重绘的 UI 需要更新。 感谢您的帮助。我已经按照你的建议做了,现在应该可以工作了。此 ViewModel 继承自在其内部实现了 INotifyPropertyChanged 接口的基类。我添加了对 RaisePropertyChanged("IsButtonEnabled"); 的调用在我的属性设置器中。我感谢您的帮助。看起来按钮并没有被禁用,但我认为这是因为代码执行速度太快,并且值以毫秒为单位切换。

以上是关于处理请求时禁用按钮的主要内容,如果未能解决你的问题,请参考以下文章

AJAX 请求时禁用按钮

当按钮被禁用时,在提交按钮前添加加载图标

vue router拦截器防止重复点击

如何在等待 redux 解决时禁用按钮?

空闲资源忙时测试 UI

防止重复数据