我正在学习MVVM,到目前为止一直都很好,除非在验证时禁用按钮。我的验证完美无缺,因此禁用按钮部分。这是我的代码:
ViewModelBase:
topMargin="20"
我的验证课程:
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
我的ViewModel:
public class NumberValidation : ValidationRule
{
public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
{
if (String.IsNullOrEmpty(value.ToString()))
{
return new ValidationResult(false, "No debe estar vacio");
}
double result = 0;
bool canConvert = double.TryParse(value as string, out result);
return new ValidationResult(canConvert, "No es numero valido");
}
}
}
我的XML以这种方式绑定:
public class CommercePayment : ViewModelBase
{
private ICommand _SubmitCommand;
private PayCommerce _payCommerce;
public PayCommerce PayCommerces
{
get
{
return _payCommerce;
}
set
{
_payCommerce = value;
NotifyPropertyChanged("PayCommerces");
}
}
public CommercePayment()
{
PayCommerces = new PayCommerce();
}
void PayCommerce_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
NotifyPropertyChanged("PayCommerces");
}
public void Submit()
{
var test = PayCommerces.AccountNumber;
var test2 = PayCommerces.PaymentAmount;
// var test2 = PayCommerces.Commerce.MerchantFullName;
}
#region Helpers
public ICommand SubmitCommand
{
get
{
if (_SubmitCommand == null)
{
_SubmitCommand = new RelayCommand(param => this.Submit(),
null);
}
return _SubmitCommand;
}
}
#endregion
}
在我的代码隐藏中,我有这个(正在测试和学习):
<Controls:Tile x:Name="tlProcesar" Title=""
TiltFactor="2"
Width="Auto" Height="Auto"
Count="Procesar"
Command="{Binding SubmitCommand}" Margin="185,189,200,-59"
>
</Controls:Tile>
如果我将控制绑定更改为:
private void Save_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = IsValid(sender as DependencyObject);
}
private void Save_Executed(object sender, ExecutedRoutedEventArgs e)
{
ViewModel.CommercePayment payments = new ViewModel.CommercePayment();
payments.Submit();
}
private bool IsValid(DependencyObject obj)
{
return !Validation.GetHasError(obj) && LogicalTreeHelper.GetChildren(obj).OfType<DependencyObject>().All(IsValid);
}
然后该按钮被禁用,但当然我在ViewModel中的Submit()方法中没有返回数据,因为它没有绑定。如果我保持原样,即使验证失败,按钮仍然可以正常工作。我该怎么办?
更新1:
创建了这个:
Command="ApplicationCommands.Save"
现在我想我需要将它与验证联系起来?
答案 0 :(得分:0)
通常,您可以将Button的IsEnabled属性绑定到xaml.cs中的Property,返回“IsValid”状态。
<Controls:Tile x:Name="tlProcesar" Title=""
TiltFactor="2"
Width="Auto" Height="Auto"
Count="Procesar"
Command="{Binding SubmitCommand}" Margin="185,189,200,-59"
IsEnabled="{Binding IsValidProperty}">
</Controls:Tile>
答案 1 :(得分:0)
我可以看到你在设置中混合了两种验证解决方案,一半发生在视图中,另一种发生在视图模型中。
您正在实现NumberValidation类,但我没有看到任何使用它的xaml代码。你需要在你的xaml代码中使用它,像这样:
<TextBox.Text>
<Binding Path="PayCommerces">
<Binding.ValidationRules>
<val:NumberValidation/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
但是如果您使用此方法,则验证在View层中完成。因此,这意味着您的ViewModel不知道它有错误,并且您的IsValid没有检测到存在错误。
如果要将所有验证放在视图中,请使用multibinding在错误控件和按钮之间添加绑定。你可以在这里看到一个例子。 Disabling button on Validation error
但是,如果您希望在ViewModel中进行验证,则需要使用视图模型来实现IDataErrorInfo接口。那么你的NumberValidation类将毫无用处。