簡體   English   中英

CanExecute()返回true,並且按鈕仍被禁用

[英]CanExecute() returns true and button is still disabled

我在Windows Phone特定頁面中有一個BottomAppBar.AppBarButton ,它綁定到中繼命令。 代碼,綁定和viewmodel的實現在項目的其他頁面上都以基本上相同的方式使用,並且完全按預期運行。

在這種特定情況下的問題是,即使在提高.RaiseCanExecuteChanged()方法之后,按鈕仍保持禁用狀態,並且CanExecute()返回true

我原本以為這可能是由於過多的調用而導致的,這些調用是通過手動更改屬性更改來手動引發通知的,所以收緊了我那部分代碼,以便僅在需要時以及在需要更改按鈕狀態時才引發該方法。 即使CanExecute()返回true ,按鈕仍保持禁用CanExecute() 如果我注釋掉CanExecute()所有檢查並將其默認設置為true,則該按鈕將按預期啟用,並且在點RelayCommand會觸發預期的Execute()函數,因此似乎可以執行RelayCommand的初始化。 如果我然后放回檢查,並在每次觸發CanExecute()CanExecute() ,則當它返回true時,該按鈕不會啟用。

有任何想法嗎? 對於它的價值,我在下面添加了代碼,但我不認為這是原因。

RelayCommand類是VS中HubApp隨附的標准類,因此我將省略該代碼。

viewmodel構造函數的最后一行是RelayCommand;

AddStrikeTeamCommand = new RelayCommand(async() => await AddStrikeTeam(), CanAddStrikeTeam);

可以添加是;

private bool CanAddStrikeTeam()
{
    //if (NameWorking == string.Empty) return false;
    //if (FactionWorking == string.Empty) return false;
    //if (PointsLimitWorking < 1) return false;
    //if (!IsValidTeamWorking) return false;
    return true;
}

最后,按鈕綁定

<AppBarButton x:Name="accept" Icon="Accept" Label="accept"
              Command="{Binding AddStrikeTeamCommand}"/>

我可能打賭您的問題與RaiseCanExecuteChanged()有關。 如果您習慣使用WPF及其如何為您自動刷新CanExecute,則尤其如此。 查看此Delegate Command實現:

http://codepaste.net/ho9s5a

ICommand接口定義事件CanExecuteChanged ,該事件指示按鈕(或UI元素)刷新其“ Enabled狀態。 在WPF中,這是由靜態命令管理器不斷提出的。 在WinRT中不存在。 在WPF中,由於它頻繁出現,因此WPF開發人員必須注意CanExecute()不是昂貴的操作。 WinRT提供了昂貴的測試,但因此要求開發人員手動引發事件。 我希望這是有道理的。

我處理此問題的一種方法是:

DelegateCommand _SaveCommand = null;
public DelegateCommand SaveCommand
{
    get
    {
        if (_SaveCommand != null)
            return _SaveCommand;
        _SaveCommand = new DelegateCommand
        (
            () =>
            {
                // TODO
            }, 
            () => true
        );
        this.PropertyChanged += (s, e) => _SaveCommand.RaiseCanExecuteChanged();
        return _SaveCommand;
    }
}

這基本上是基於(通常在我的View模型中)任何屬性的更改刷新CanExecute的。 如果您對ObservableCollection中的模型進行了潛在的更改,這還不夠,但這是整個過程的一個很好的開始。

您可能根本沒有這個問題。 而且您正在打電話提出該事件,該事件返回true,並且仍然無法正常工作。 如果正在發生這種情況,那么它就必須是您的代碼,因為Commands正在為數千個應用程序工作。 但是,如果您想將代碼發送給我,我會看一下。

祝你好運!

我知道這是一個較晚的答案,但此帖子已鏈接到另一個問題,因此我覺得我應該發布一個更好的代碼示例。

傑里的答案很可能是正確的,問題是在該ICommand實現中不會自動引發RaiseCanExecuteChanged ,但是提供的代碼示例重新引入了導致該錯誤首先出現的相同問題-每當問題時,它都會引發CanExecuteChanged屬性更改,導致CanExecute的調用遠遠超出了必要。

PropertyChanged事件處理程序應包括一個檢查,並且如果更改的屬性是CanExecute中使用的屬性,則僅引發CanExecuteChanged。

由於您的CanExecute是

private bool CanAddStrikeTeam()
{
    if (NameWorking == string.Empty) return false;
    if (FactionWorking == string.Empty) return false;
    if (PointsLimitWorking < 1) return false;
    if (!IsValidTeamWorking) return false;
    return true;
}

那么事件處理程序僅在屬性之一更改時才需要引發CanExecuteChanged

this.PropertyChanged += (s, e) => 
{
    switch (e.PropertyName)
    {
        case "NameWorking":
        case "FactionWorking":
        case "PointsLimitWorking":
        case "IsValidTeamWorking":
            AddStrikeTeamCommand.RaiseCanExecuteChanged();
            break;
    }
}

如果使用的是Mvvm Light,請確保包含GalaSoft.MvvmLight.CommandWpf命名空間,而不是GalaSoft.MvvmLight.Command命名空間。 (請參閱有關MVVM RelayCommand CanExecute的第二個答案)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM