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

时间:2016-01-26 14:24:15

标签: c# wpf mvvm data-binding datagrid

我正在练习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 进行绑定的逻辑。

1 个答案:

答案 0 :(得分:4)

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应该是一个公共属性,因此您可以使用Databinding,例如:

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

根据提交中的问题进行编辑:

您需要将TextBoxes的text属性绑定到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));
            }
        }


    }

当然现在你的ViewModel和Model需要实现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));
        }
    }
}

EDIT2 - 忘了添加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>