使用MVVM时如何禁用验证错误按钮?

时间:2015-11-24 14:09:52

标签: c# wpf validation mvvm

我正在学习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"

现在我想我需要将它与验证联系起来?

2 个答案:

答案 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类将毫无用处。