如何在我的方案中使用 MVVM 动态更新数据网格

本文关键字:动态 MVVM 更新 数据 网格 数据网 我的 方案 | 更新日期: 2023-09-27 18:32:00

我正在练习MVVM应用程序,我是初学者,我想做的是,我在网格中有3行,第一行将包含3个标签和3个相应的按钮。第二行将包含一个按钮,用于保存在该文本框中输入的数据。第三行将包含具有相同数量和类型的文本框(三个)的数据网格。

看这里可以看到 http://prntscr.com/9v2336

用户将在第一行输入数据,然后按第二行的保存按钮,然后他必须在相应的数据网格列中找到写入的信息。

我的尝试在这里(整个代码):

视图:

<Window x:Class="WpfApplication4.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">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
            <RowDefinition Height="30"></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>
        <Grid Grid.Row="0">
            <Grid.RowDefinitions>
                <RowDefinition></RowDefinition>
                <RowDefinition></RowDefinition>
                <RowDefinition></RowDefinition>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition></ColumnDefinition>
                <ColumnDefinition></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <TextBox Grid.Column="1" Grid.Row="0" Text="{Binding TextName}" Height="20" Width="80" HorizontalAlignment="Center"></TextBox>
            <TextBox Grid.Column="1" Grid.Row="1" Text="{Binding RollNumber}"  Height="20" Width="80"></TextBox>
            <TextBox Grid.Column="1" Grid.Row="2" Text="{Binding Class}" Height="20" Width="80"></TextBox>
            <Label Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center">Name</Label>
            <Label Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center">RollNumber</Label>
            <Label Grid.Row="2" HorizontalAlignment="Center" VerticalAlignment="Center">Class</Label>
        </Grid>
        <Grid Grid.Row="1" >
            <Button Width="80" Height="20" Command="{Binding saveStudentRecord}"> Save</Button>
        </Grid>
        <Grid Grid.Row="2">
            <DataGrid ItemsSource="{Binding DGrid}">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="Name" Binding="{Binding dgName}" Width="150"></DataGridTextColumn>
                    <DataGridTextColumn Header="Rollnumber" Binding="{Binding dgRollnumber}" Width="150"></DataGridTextColumn>
                    <DataGridTextColumn Header="Class" Binding="{Binding dgClass}" Width="150"></DataGridTextColumn>
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
    </Grid>
</Window>

型:

 class Model
    {
        private string textName;
        public string TextName
        {
            get { return textName; }
        }
        private string rollNumber;
        public string RollNumber
        {
            get { return rollNumber; }
        }
        private string cclass;
        public string Class
        {
            get { return cclass; }
        }
    }

视图模型:

   class ViewModel
    {
        public bool canExecute { get; set; }
        private RelayCommand saveStudentRecord; 
        private ObservableCollection<Model> dGrid;
        public ViewModel()
        {
        }
        private void MyAction()
        {
           //What to do here to pass all that data to the datagrid corresponding columns
        }     
    }

我在哪里有问题?我已经设计了整个正文,但我无法找到如何在按钮单击事件上将文本框中输入的数据分配给相应的数据网格列并仅使用 MVVM 绑定它们的逻辑。

如何在我的方案中使用 MVVM 动态更新数据网格

应该

很简单,就像向ObservableCollection<Model> DGrid添加新模型一样:

 class ViewModel
    {
        public bool canExecute { get; set; }
        private RelayCommand saveStudentRecord; 
        private ObservableCollection<Model> dGrid;
        public ViewModel()
        {
            dGrid = new ObservableCollection<Model>();
        }
        private void MyAction()
        {
           dGrid.Add(new Model(){
               TextName = valueOfTextTextBox,
               RollNumber = valueOfRollNumberTextBox,
               Class = valueOfClassTextBox
           });
        }     
    }

这里要记住的事情:dGrid 应该是一个公共属性,因此您可以将数据绑定与它一起使用,例如:

public ObservableCollection<Model> dGrid {
    get;
    private set;
}

根据表彰中的问题进行编辑:

您需要将文本框的文本属性绑定到 ViewModel 上的属性。由于ModelClass拥有这种信息,我会这样做:

 class ViewModel
    {
        public bool canExecute { get; set; }
        private RelayCommand saveStudentRecord; 
        private ObservableCollection<Model> dGrid;
        public ViewModel()
        {
            dGrid = new ObservableCollection<Model>();
        }
        public Model EditedModel {
            get {
                return _editedModel;
            }
            set {
                _editedModel = value;
                SignalPropertyChanged("EditedModel");
            }
        }
        private void MyAction()
        {
           dGrid.Add(EditedModel);
           EditedModel = new Model();
        }
        void SignalPropertyChanged(string propertyName){
            if(propertyChanged !=null){
                propertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

    }

当然,现在您的视图模型和模型需要实现INotifyPropertyChanged接口来通知视图更改

class Model : INotifyPropertyChanged
{
    private string textName;
    public string TextName
    {
        get { return textName; }
        set { 
            textName = value; 
            SignalPropertyChanged("TextName");
         }
    }
    private string rollNumber;
    public string RollNumber
    {
        get { return rollNumber; }
        set { 
            rollNumber= value; 
            SignalPropertyChanged("RollNumber");
         }
    }
    private string cclass;
    public string Class
    {
        get { return cclass; }
        set { 
            cclass= value; 
            SignalPropertyChanged("Class");
         }
    }
    public event PropertyChangedEventHandler propertyChanged;
    void SignalPropertyChanged(string propertyName){
        if(propertyChanged !=null){
            propertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

编辑2 - 忘记添加 XAML 部件:)您需要将文本框绑定到新属性

<Window x:Class="WpfApplication4.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">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
            <RowDefinition Height="30"></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>
        <Grid Grid.Row="0">
            <Grid.RowDefinitions>
                <RowDefinition></RowDefinition>
                <RowDefinition></RowDefinition>
                <RowDefinition></RowDefinition>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition></ColumnDefinition>
                <ColumnDefinition></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <TextBox Grid.Column="1" Grid.Row="0" Text="{Binding EditedModel.TextName}" Height="20" Width="80" HorizontalAlignment="Center"></TextBox>
            <TextBox Grid.Column="1" Grid.Row="1" Text="{Binding EditedModel.RollNumber}"  Height="20" Width="80"></TextBox>
            <TextBox Grid.Column="1" Grid.Row="2" Text="{Binding EditedModel.Class}" Height="20" Width="80"></TextBox>
            <Label Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center">Name</Label>
            <Label Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center">RollNumber</Label>
            <Label Grid.Row="2" HorizontalAlignment="Center" VerticalAlignment="Center">Class</Label>
        </Grid>
        <Grid Grid.Row="1" >
            <Button Width="80" Height="20" Command="{Binding saveStudentRecord}"> Save</Button>
        </Grid>
        <Grid Grid.Row="2">
            <DataGrid ItemsSource="{Binding DGrid}">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="Name" Binding="{Binding dgName}" Width="150"></DataGridTextColumn>
                    <DataGridTextColumn Header="Rollnumber" Binding="{Binding dgRollnumber}" Width="150"></DataGridTextColumn>
                    <DataGridTextColumn Header="Class" Binding="{Binding dgClass}" Width="150"></DataGridTextColumn>
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
    </Grid>
</Window>