一次验证4个组合框的从属数据c#

一次验证4个组合框的从属数据c#,c#,wpf,mvvm,C#,Wpf,Mvvm,我正在学习使用WPF的MVVMC,我需要一次验证4个组合框。背后的逻辑是,选择必须是相同类型的ad族(填充这些组合框的对象的两个属性)。问题是,它们必须结合评估,我一直在从这个网站、MSDN甚至我的课程中找到这些问题的答案 首先,我应该把我的评估代码放在哪里? 目前,代码位于我构建的窗口的ViewModel文件中。该验证代码的一个片段如下所示 //Temperature Check private void CheckTemperature() { if (

我正在学习使用WPF的MVVMC,我需要一次验证4个组合框。背后的逻辑是,选择必须是相同类型的ad族(填充这些组合框的对象的两个属性)。问题是,它们必须结合评估,我一直在从这个网站、MSDN甚至我的课程中找到这些问题的答案

首先,我应该把我的评估代码放在哪里? 目前,代码位于我构建的窗口的ViewModel文件中。该验证代码的一个片段如下所示

    //Temperature Check
    private void CheckTemperature()
    { 
      if (Temperature < -273.15)
      {
        MessageBox.Show("You can't use temperatures below 0ºK", "It's freezing");
        Temperature = -273.15;
      }
      else if (Temperature > 100)
      {
        MessageBox.Show("Surface temperature can't be that hot", "Hotter than hell");
        Temperature = 100;
      }
      CanObtainHarm();
    }
我的常识告诉我,这里不是验证代码的所在地。 对于这个例子,我将把它作为一个验证规则,但是4个组合框必须进行验证,如果它们没有正确设置,它们应该保持为空,这让我很疯狂。 由于我还没有发现如何验证用户的组合框输入,如果输入无效,则将其保留为空,所以我从视频跳到帖子。 其他信息:
没有按下验证的按钮,每次更改这些组合框的值时都应执行验证

我将此任务归结为:

  • 一次验证4个组合框的从属数据c#
  • 当这4个属性中的任何一个发生更改时,运行一些验证逻辑
  • 在属性更改时,如果propertyName=4中的一个,则运行一些验证逻辑
  • INotifyPropertyChanged.PropertyChanged,开关语句,验证逻辑
因此,在对视图模型有引用的地方,我们需要向其PropertyChanged事件添加一个事件处理程序,以检查属性名称是否为4个事件之一,如果是,则运行一些验证逻辑

鉴于我们的视图模型是视图上的一个依赖属性,我将把所有这些连接到视图的Loaded事件中

所有视图模型的ANotifyPropertyChanged-base实现

using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace SO60283924
{
    public abstract class ANotifyPropertyChanged : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void SetProperty<T>(ref T backingStore, T newValue, [CallerMemberName] string propertyName = "")
        {
            var areEqual = ReferenceEquals(backingStore, newValue);
            if (areEqual)
                return;
            backingStore = newValue;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
主窗口-某些视图模型的视图

<Window
    x:Class="SO60283924.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Loaded="Window_Loaded">
    <Grid>

    </Grid>
</Window>

这就实现了我们的目标:在属性更改时,如果4个属性中的一个发生了更改,请运行一些验证逻辑。

您可以找到一个很好的教程开始。在您的情况下,我会使用IDataErrorInfo验证或绑定组。只是一个建议:请不要在代码中使用
MessageBox.Show
,因为它绝对不符合MVVM。您是否研究过@II Vic建议的绑定组?看起来他们是你最好的选择。否则,您将不得不考虑一种解决方案,该方法在组合框绑定到4个属性中的每一个调用相同的验证方法,并在4个属性设置器中的每一个中为所有4个属性提高每个属性通知事件,以指示由于另一个属性更改可能会发生验证更改。
namespace SO60283924
{
    public class SomeViewModel : ANotifyPropertyChanged
    {
        private string someString;
        private int someInt;
        private object someObject;
        private decimal someDecimal;
        private object somePropertyNotPartOfValidation;

        public string SomeString { get => someString; set => SetProperty(ref someString, value); }
        public int SomeInt { get => someInt; set => SetProperty(ref someInt, value); }
        public object SomeObject { get => someObject; set => SetProperty(ref someObject, value); }
        public decimal SomeDecimal { get => someDecimal; set => SetProperty(ref someDecimal, value); }
        public object SomePropertyNotPartOfValidation { get => somePropertyNotPartOfValidation; set => SetProperty(ref somePropertyNotPartOfValidation, value); }
    }
}
<Window
    x:Class="SO60283924.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Loaded="Window_Loaded">
    <Grid>

    </Grid>
</Window>
using System.Windows;

namespace SO60283924
{
    public partial class MainWindow : Window
    {
        public SomeViewModel SomeViewModel
        {
            get { return (SomeViewModel)GetValue(SomeViewModelProperty); }
            set { SetValue(SomeViewModelProperty, value); }
        }
        public static readonly DependencyProperty SomeViewModelProperty =
            DependencyProperty.Register(nameof(SomeViewModel), typeof(SomeViewModel), typeof(MainWindow), new PropertyMetadata(new SomeViewModel()));
        public MainWindow()
        {
            InitializeComponent();
        }
        void Window_Loaded(object sender, RoutedEventArgs e)
        {
            SomeViewModel.PropertyChanged += (_, propertyChangedEventArgs) =>
            {
                switch (propertyChangedEventArgs.PropertyName)
                {
                    case nameof(SomeViewModel.SomeDecimal):
                    case nameof(SomeViewModel.SomeInt):
                    case nameof(SomeViewModel.SomeObject):
                    case nameof(SomeViewModel.SomeString):
                        //TODO add validation code
                        break;
                }
            };
        }
    }
}