【发布时间】:2014-07-05 10:14:37
【问题描述】:
我正在迈出在我的 Windows Phone 应用程序中使用命令(通过实现ICommand 接口)的第一步。现在我遇到了一个我似乎无法弄清楚的问题。我正在将一个控件(在本例中是一个文本框)绑定到 Button 的 CommandParameter 属性:
<Button x:Name="BTN_Search"
Style="{StaticResource ButtonNoPressedStyle}"
BorderThickness="0"
ccontrols:TiltEffect.IsTiltEnabled="True"
Grid.Column="1"
Height="85"
Margin="0,0,0,-2"
CommandParameter="{Binding ElementName=TB_Search}"
Command="{Binding SearchTermCommand}">
<Button.Background>
<ImageBrush ImageSource="/Assets/Images/searchbtn.png" />
</Button.Background>
</Button>
当应用程序启动并实例化视图模型时,CanExecute 方法会连续触发两次。
public override bool CanExecute(object parameter)
{
if (parameter != null)
{
var textbox = parameter as TextBox;
if ((textbox.DataContext as MainPageViewmodel).SearchTerm == null)
{
(textbox.DataContext as MainPageViewmodel).SearchTerm = "";
return true;
}
else if (String.IsNullOrWhiteSpace(textbox.Text)) return false;
else if (textbox.Text.Any(Char.IsDigit)) return false;
else if (textbox.Text.Length < 4) return false;
else if (_commandExecuting) return false;
else
{
var bindingExpression = textbox.GetBindingExpression(TextBox.TextProperty);
bindingExpression.UpdateSource();
return true;
}
}
return true;
}
第一次参数是null,第二次它包含文本框。由于这种行为,我必须让前两次,CanExecute 方法返回 true,否则按钮将被禁用。
我已经阅读了一些可能与RaiseCanExecuteChanged() 有关的其他主题,但我也不太确定。
这个question
有一些关于这个问题的答案,但这些答案不符合我的需要,因为大多数解决方案都是针对 WPF(使用 CommandManager 或 IMultiValueConverter)而其他的似乎不起作用。
是否有任何解决方案可以确保CanExecute 只触发一次,或者这种行为的解释是什么?
【问题讨论】:
-
在“CanExecute”的测试中更新绑定表达式似乎是在滥用 ICommand 模式。为什么需要这样做?
-
因为我有这样的想法,即仅在需要时(满足所有要求时)进行更新。在研究了这个之后,我想我可以将 INotifyPropertyChanged 添加到有问题的属性中。感谢您引起我的注意。但我仍然想知道为什么会这样。
-
我不知道究竟是为什么,但这个猜测对我来说是有道理的:第一次检查是什么时候第一次构造命令对象;第二个检查是绑定 CommandParameter 时(即加载 TB_Search 元素)。
-
这意味着每个与命令绑定的控件或属性在加载或更新时触发 RaiseCanExecuteChanged()?
-
好问题,我真的不知道...根据经验,通过 NotifyPropertyChanged 不触发它的属性更改。依赖属性改变?视觉树的变化?不知道...
标签: c# xaml windows-phone-8 icommand