C# wpf mvvm如何使用icommand验证数据?

C# wpf mvvm如何使用icommand验证数据?,c#,wpf,mvvm,icommand,C#,Wpf,Mvvm,Icommand,我是WPF开发的新手,我对谷歌也没有进一步的了解。我不明白如何使用ICommand验证模型数据。我知道有注释,并且ICommand接口提供了canExecute方法。例如,我想说姓名和姓氏是必需的。 我在我的模型类中用[Required(ErrorMessage=“Title is Required.”]进行了尝试,但没有成功。也许有人能帮我 到目前为止,我有以下几点: public class Student : INotifyPropertyChanged { private str

我是WPF开发的新手,我对谷歌也没有进一步的了解。我不明白如何使用
ICommand
验证模型数据。我知道有注释,并且
ICommand
接口提供了
canExecute
方法。例如,我想说姓名和姓氏是必需的。 我在我的模型类中用
[Required(ErrorMessage=“Title is Required.”]
进行了尝试,但没有成功。也许有人能帮我

到目前为止,我有以下几点:

public class Student : INotifyPropertyChanged
{
    private string name;
    private string surname;
    private int age;
    private string course;

    public string Course
    {
        get { return course; }
        set 
        { 
            course = value;
            OnPropertyChanged();
        }
    }

    public int Age
    {
        get { return age; }
        set
        {
            age = value;
            OnPropertyChanged();
        }
    }

    public string Surname
    {
        get { return surname; }
        set
        {
            surname = value;
            OnPropertyChanged();
        }
    }

    public string Name
    {
        get { return name; }
        set
        {
            name = value;
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged([CallerMemberName] string name = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }
}



public class StudentViewModel
{
    private IList<Student> _studentList;

    public StudentViewModel()
    {
        _studentList = new List<Student>
        {
            new Student{Name="Todd",Surname="Johnsen",Age=29,Course="Software-Development"},
            new Student{Name="Mike",Surname="Kroshka",Age=31,Course="Marketing"},
            new Student{Name="Marie",Surname="Tedd",Age=21,Course="Marketing"},
            new Student{Name="Susane",Surname="Müller",Age=31,Course="Marketing"},
            new Student{Name="Herbert",Surname="Rehl",Age=18,Course="Software-Development"},
            new Student{Name="Markus",Surname="Stanz",Age=23,Course="Software-Development"},
            new Student{Name="Sabine",Surname="Bergsen",Age=19,Course="Marketing"}
        };
    }

    public IList<Student> Students
    {
        get { return _studentList; }
        set { _studentList = value; }
    }

    private ICommand mUpdater;
    public ICommand UpdateCommand
    {
        get
        {
            if(mUpdater == null)
            {
                mUpdater = new Updater();
            }
            return mUpdater;
        }
        set
        {
            mUpdater = value;
        }
    }
}

 public class Updater : ICommand
{
    public bool CanExecute(object parameter)
    {
        return true;
    }

    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter)
    {
        
    }
}

<Window x:Class="Student_list_mvvm_wpf_core.MainWindowView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:Student_list_mvvm_wpf_core"
    mc:Ignorable="d"
    Title="Student-list" Height="350" Width="600">
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="auto"></ColumnDefinition>
        <ColumnDefinition Width="*"></ColumnDefinition>
        <ColumnDefinition Width="*"></ColumnDefinition>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="auto"></RowDefinition>
        <RowDefinition Height="auto"></RowDefinition>
        <RowDefinition Height="auto"></RowDefinition>
        <RowDefinition Height="auto"></RowDefinition>
        <RowDefinition Height="*"></RowDefinition>
    </Grid.RowDefinitions>
    
    <Label Grid.Row="0">Name</Label>
    <Label Grid.Row="1">Surname</Label>
    <Label Grid.Row="2">Age</Label>
    <Label Grid.Row="3">Course</Label>
    <Button x:Name="btnUpdateStudent" Grid.Row="3" Grid.Column="2"
            Width="100" Margin="2" HorizontalAlignment="Left"
            Command="{Binding Path=UpdateCommand}">Update Student</Button>
    <ListView x:Name="studentGrid" ItemsSource="{Binding Students}"
              Grid.Row="4" Grid.ColumnSpan="3" Margin="5">
        <ListView.View>
            <GridView x:Name="gridStudent">
                <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" Width="100" />
                <GridViewColumn Header="Surname" DisplayMemberBinding="{Binding Surname}" Width="100" />
                <GridViewColumn Header="Age" DisplayMemberBinding="{Binding Age}" Width="50" />
                <GridViewColumn Header="Course" DisplayMemberBinding="{Binding Course}" Width="200" />
            </GridView>
        </ListView.View>
    </ListView>
    <TextBox Grid.Row="0" Grid.Column="1" Width="200"
             HorizontalAlignment="Left" Margin="2"
             Text="{Binding SelectedItem.Name, ElementName=studentGrid}"
             x:Name="txtName"></TextBox>
    <TextBox Grid.Row="1" Grid.Column="1" Width="200"
             HorizontalAlignment="Left" Margin="2"
             Text="{Binding SelectedItem.Surname, ElementName=studentGrid}"
             x:Name="txtSurname"></TextBox>
    <TextBox Grid.Row="2" Grid.Column="1" Width="200"
             HorizontalAlignment="Left" Margin="2"
             Text="{Binding SelectedItem.Age, ElementName=studentGrid}"
             x:Name="txtAge"></TextBox>
    <TextBox Grid.Row="3" Grid.Column="1" Width="200"
             HorizontalAlignment="Left" Margin="2"
             Text="{Binding SelectedItem.Course, ElementName=studentGrid}"
             x:Name="txtCourse"></TextBox>
</Grid>
公共类学生:INotifyPropertyChanged
{
私有字符串名称;
私家姓;
私人互联网;
私人弦乐课程;
公共弦乐课程
{
获取{返回路线;}
设置
{ 
课程=价值;
OnPropertyChanged();
}
}
公共信息
{
获取{返回年龄;}
设置
{
年龄=价值;
OnPropertyChanged();
}
}
公共字符串姓氏
{
获取{返回姓氏;}
设置
{
姓氏=价值;
OnPropertyChanged();
}
}
公共字符串名
{
获取{返回名称;}
设置
{
名称=值;
OnPropertyChanged();
}
}
公共事件属性更改事件处理程序属性更改;
public void OnPropertyChanged([CallerMemberName]字符串名称=null)
{
PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(名称));
}
}
公共课堂学生视图模型
{
私立IList_学生名单;
公共学生视图模型()
{
_studentList=新列表
{
新学生{Name=“Todd”,姓氏=“Johnsen”,年龄=29岁,课程=“软件开发”},
新学生{Name=“Mike”,姓氏=“Kroshka”,年龄=31岁,课程=“营销”},
新学生{Name=“Marie”,姓氏=“Tedd”,年龄=21岁,课程=“营销”},
新生{Name=“Susane”,姓氏=“Müller”,年龄=31岁,课程=“营销”},
新学生{Name=“Herbert”,姓氏=“Rehl”,年龄=18岁,课程=“软件开发”},
新学生{Name=“Markus”,姓氏=“Stanz”,年龄=23岁,课程=“软件开发”},
新生{Name=“Sabine”,姓氏=“Bergsen”,年龄=19岁,课程=“营销”}
};
}
公立学校学生
{
获取{return\u studentList;}
设置{u studentList=value;}
}
私人ICommand mUpdater;
公共ICommand更新命令
{
得到
{
if(mUpdater==null)
{
mUpdater=新的更新程序();
}
返回mUpdater;
}
设置
{
mUpdater=值;
}
}
}
公共类更新程序:ICommand
{
公共布尔CanExecute(对象参数)
{
返回true;
}
公共事件处理程序CanExecuteChanged;
public void Execute(对象参数)
{
}
}
名称
姓
年龄
课程
更新学生
使用验证模型看起来更适合您的情况首先,更新您的
视图模型
,使其具有绑定到
列表视图
SelectedItem

  public Student SelectedStudent
  {
        get { return _selectedStudent; }
        set { _selectedStudent = value; }
  }
第二次,更新学生的模型以进行数据验证:

public class Student : INotifyPropertyChanged, IDataErrorInfo
{
    private string name;
    private string surname;
    private int age;
    private string course;

    public string Course
    {
        get { return course; }
        set
        {
            course = value;
            OnPropertyChanged();
        }
    }

    public int Age
    {
        get { return age; }
        set
        {
            age = value;
            OnPropertyChanged();
        }
    }

    public string Surname
    {
        get { return surname; }
        set
        {
            surname = value;
            OnPropertyChanged();
        }
    }

    public string Name
    {
        get { return name; }
        set
        {
            name = value;
            OnPropertyChanged();
        }
    }

    public string Error => string.Empty;
    public string this[string columnName]
    {
        get
        {
            string result = null;
            if (columnName == "Name")
            {
                if (string.IsNullOrEmpty(Name))
                    result = "Name is required.";
            }
            if (columnName == "Surname")
            {
                if (string.IsNullOrEmpty(Surname))
                    result = "Surname is required.";
            }
            return result;
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged([CallerMemberName] string name = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }
}
最后,更新您的xaml: -在
列表视图的
SelectedItem
和您创建的属性之间绑定。 -验证
文本框的
文本

<TextBox Grid.Row="0" Grid.Column="1" Width="200"
         HorizontalAlignment="Left" Margin="2"
         Text="{Binding SelectedStudent.Name,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=true, NotifyOnValidationError=False}"
         x:Name="txtName"></TextBox>
    <TextBox Grid.Row="1" Grid.Column="1" Width="200"
         HorizontalAlignment="Left" Margin="2"
         Text="{Binding SelectedStudent.Surname,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=true, NotifyOnValidationError=False}"
         x:Name="txtSurname"></TextBox>
输出:


这里是一个完整的源代码。如果您坚持使用
canExecute
,应该会有所帮助。

谢谢您的努力@不客气,如果答案有用,请接受:)
<Button x:Name="btnUpdateStudent" Grid.Row="3" Grid.Column="2"
        Width="100" Margin="2" HorizontalAlignment="Left"
         Content="Update Student" Command="{Binding UpdateCommand}">
        <Button.Style>
            <Style TargetType="{x:Type Button}">
                <Setter Property="IsEnabled" Value="False" />
                <Style.Triggers>
                    <MultiDataTrigger>
                        <MultiDataTrigger.Conditions>
                            <Condition Binding="{Binding ElementName=txtName, Path=(Validation.HasError)}" Value="false" />
                            <Condition Binding="{Binding ElementName=txtSurname, Path=(Validation.HasError)}" Value="false" />
                        </MultiDataTrigger.Conditions>
                        <Setter Property="IsEnabled" Value="True" />
                    </MultiDataTrigger>
                </Style.Triggers>
            </Style>
        </Button.Style>
    </Button>