我在Windows 8.1'通用'应用中有一个按钮绑定到RelayCommand
,根据CanExecute()
的返回值,该按钮未按预期更新为已禁用。
实现细节如下,但基本上,RelayCommand
初始化为返回false,更改为按预期启用,但不会按预期返回到禁用状态。
UI流程是用户从组合框中选择一个项目(绑定到属性),调用.RaiseCanExecuteChanged()
并返回true,按钮更新为按预期启用。第二个组合框(现在可见)绑定到另一个属性,该属性在更改时运行一个方法来设置验证属性,当更改时调用.RaiseCanExecuteChanged()
。这一次,当我希望看到按钮被禁用时,它不是,尽管CanExecute()
返回false。有趣的是,如果单击该按钮,则该动作的委托方法不会运行,但我需要禁用该按钮,因为该按钮的click
方法为Frame.GoBack()
RelayCommand类:
public class RelayCommand : ICommand
{
private readonly Action _execute;
private readonly Func<bool> _canExecute;
public event EventHandler CanExecuteChanged;
public RelayCommand(Action execute)
: this(execute, null)
{
}
public RelayCommand(Action execute, Func<bool> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute;
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute();
}
public void Execute(object parameter)
{
_execute();
}
public void RaiseCanExecuteChanged()
{
var handler = CanExecuteChanged;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
}
CanExecute方法:
private bool CanAcceptTransportProfile()
{
if (IsTPInEditMode == false) return false;
if (SelectedTransport == null) return false;
if (IsSubPropertiesValid == false) return false;
return true;
}
初始属性和更改:
public Unit SelectedTransport
{
get { return _selectedTransport; }
set
{
if (_selectedTransport != value)
{
_selectedTransport = value;
RaisePropertyChanged("SelectedTransport");
OnSelectedTransportChange();
}
}
}
private void OnSelectedTransportChange()
{
switch (SelectedTransport == null)
{
case true:
IsTransportSelected = false;
IsUnitsPerTransportValid = true;
IsSharingWithValid = true;
IsNestingValid = true;
break;
case false:
IsTransportSelected = true;
ShowUnitsPerTransportSelector = IsAllowedToShareTransport ? false : true;
break;
}
CommandAcceptTransportProfile.RaiseCanExecuteChanged();
}
第二次财产变更:
public int UnitsPerTransport
{
get { return _unitsPerTransport; }
set
{
if (_unitsPerTransport != value)
{
_unitsPerTransport = value;
RaisePropertyChanged("UnitsPerTransport");
OnUnitsPerTransportChange();
}
}
}
private void OnUnitsPerTransportChange()
{
List<int> unitoptions = UnitHelper.UnitRangeFromSquadSize(this.SquadSize);
if (!unitoptions.Contains(_unitsPerTransport))
{
foreach (int num in unitoptions)
{
if (_unitsPerTransport < num)
{
if (num % _unitsPerTransport != 0)
{ goto Invalid; }
}
else
{
if (_unitsPerTransport % num != 0)
{ goto Invalid; }
}
}
goto Valid;
}
else
{ goto Valid; }
Valid:
IsUnitsPerTransportValid = true;
IsSubPropertiesValid = (IsUnitsPerTransportValid && IsNestingValid && IsSharingWithValid && IsTotalUnitsRequiredValid) ? true : false;
Invalid:
IsUnitsPerTransportValid = false;
IsSubPropertiesValid = false;
}
IsSubPropertiesValid
在发生变化时会引发CommandAcceptTransportProfile.RaiseCanExecuteChanged()
。 UnitHelper
是一个静态类,只返回ints
的列表。然后,该方法从组合框中检查所选的int,并相应地转到有效/无效。当它将IsSubPropertiesValid
设置为false时,我希望看到该按钮被禁用,而不是。
我一直在我的项目中以这种方式使用RelayCommand
并且它在每个实例中都按预期工作,除了这个,它有更复杂的验证/ Onproperty更改调用围绕它,所以我怀疑它有与此有关,但要解决这个问题超出了我自学的知识。
答案 0 :(得分:0)
尝试实现 INotifyPropertyChanged ,示例可能如下所示:
public class RelayCommand : ICommand, INotifyPropertyChanged
{
#region INotify
public event PropertyChangedEventHandler PropertyChanged;
public void RaiseCanExecuteChanged()
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, "CanExecute");
}
}
#endregion