最近在学习MVVM方面的知识,遇到一个小问题还希望懂的人来给我解答,弄了一天了还是不成功,对您来说可能一句话的事情。
我想做的功能是这样的,和这篇陈老师博客中的例子一样:http://www.cnblogs.com/chenxizhang/archive/2012/04/14/2446782.html,我的xaml文件
<Window x:Class="test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<TextBox x:Name="tbtest" Text="{Binding UserName,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"></TextBox>
<TextBox >hah</TextBox>
<Button Command="{Binding SaveCommand}" CommandParameter="{Binding UserName}">测试</Button>
</StackPanel>
</Window>
我的viewmodel代码:
namespace test {
class MainWindowViewModel:NotificationObject
{
private string userName;
public string UserName
{
get
{
return userName;
}
set
{
userName = value;
this.RaisePropertyChanged("UserName");
}
}
public ICommand SaveCommand
{
get
{
return new DelegateCommand<string>(u => MessageBox.Show(u),g=>!string.IsNullOrEmpty(g));
}
}
}
}
如果这样的话按钮直接就是不能用的,无论在文本框中输入什么都是不可用的。如果去掉条件的话按钮就能工作,不过就失去了我想要的效果。希望明白的人帮我看看,哪里除了问题。不解决的话心里总是不舒服,谢谢大家
“你好。Button不可用是因为!string.IsNullOrEmpty(g)一直为真。
也就是当g为空或者null都会导致按钮不可用。“
本来我准备提交答案了,但是我发现楼主应该是知道这一点的。
我又仔细的看了下,没有发现什么问题。
反正无聊,就用VS看了下。
不看不知道,一看吓一跳,卧槽为毛按钮不可用呢?简直颠覆这一年来的wpf开发经验、
好了说结论。
按钮不可用实际上是UserName为空造成的。
因为你在Xaml中有这样一句代码:CommandParameter="{Binding UserName}"
然后当绑定执行的时候,发现UserName是null的,然后内部经过一系列的处理,最终的结果导致了绑定部分失效了,
在这个例子里的具体表现是,绑定一直认为Command是不可执行的。
所以解决办法就是在最开始给UserName赋一个空值(比如string.Empty)
具体为何会这样,我也不太清楚。我只能帮你到这里了。
我也希望真正清楚这一机制的人能回答这一问题,然后@我
谢谢
我尝试使用MvvmLight进行绑定,发现即使UserName最开始为null,按钮依然是可用的。
所以我觉得楼主可以把它理解为WPF实现的Command上的一个bug:即CommandParameter不能传递一个null值
个人想法,不一定正确,还请各位看客多多指教。
@zhoumy: @zhoumy: 首先说一句对不起,来晚了。我登博客园的时候没有发现有新通知呢。对于您的回答,我看了之后还是没大清楚呢。我按照回答中刚开始个UserName赋值一个“”(空字符串),将g=>!string.IsNullOrEmpty(g),这样委托应该是返回false 吧。按钮应该是不能用的,但是打开还是能用。并且我用的是prism,不是MvvmLight。不过我感觉机制应该是一样的啊。谢谢你的回答。
不是WPF的bug,是你的DelegateCommand实现得有问题吧。由于你没有贴出代码,我这里给你一个简单的示例:
class TestCommand : ICommand { public event EventHandler CanExecuteChanged { add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; } } public bool CanExecute(object parameter) { return !string.IsNullOrEmpty(parameter as string); } public void Execute(object parameter) { MessageBox.Show(parameter as string); } }
你用这个TestCommand替换你的DelegateCommand<string>试试。
你好,我用的是prism中提供的DelgegateCommand<string>泛型委托。其实我对这一块普通的命令实现不是很清楚,不过也谢谢你的回答。我过天学习了之后再过来用你提供的方法。谢谢
楼主你好,这个问题我也不是很明白,能否给讲解一下?