简体   繁体   中英

Whats wrong with my MVVM approach here

I am trying to implement MVVM approach using silverlight-c# (not using galla or prism or any inbuilt things).

What I have to do: (I have a button in the first view and a grid just below that button which will be used to display a List shortly). When I press on a button it will pop-up a form on which I will enter the information and that information is supposed to be displayed in List in the area below the " Programs text in Image 1"

What I have done is :

I have succesfully created event on button click and read the data written from form by user. The problem now is I am not able to render that data read from that form by user on the area belos the **Programs .

Here you can see that I have area below the Programs and there is: Name, Author and Date Creation and many others. Just below that I want to display the data which I am going to read from the user on a Form obtained on button click ("Add Programs" button).

("Add Programs" is the button to be clicked) On clicking i got :

The code in ProgramGrid.xaml to bind the

<UserControl 
    x:Class="DEV_CENTER.ProgramGrid"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:System="clr-namespace:System;assembly=mscorlib"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
    xmlns:dataprimitives="clr-namespace:System.Windows.Controls.Primitives;assembly=System.Windows.Controls.Data"
    xmlns:local="clr-namespace:DEV_CENTER"
    xmlns:vm="clr-namespace:ViewModel;assembly=ViewModel"

    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400" >

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
        </Grid.RowDefinitions>

        <Grid Grid.Row="0" Margin="5 5 5 20" Background="White">
            <TextBox Text="">
                <TextBox.Background>
                    <ImageBrush ImageSource="Images/search_icon.png" Stretch="None" AlignmentX="Right" />
                </TextBox.Background>
            </TextBox>
        </Grid>
        <Button Click="OnClick" Grid.Row="1" Height="25" >Add Programs</Button>
        <TextBlock Text="Programs" Grid.Row="2" FontWeight="Bold"/>
        <data:DataGrid  Grid.Row="3" x:Name="gridPrograms" SelectedItem="{Binding SelectedProgram, Mode=TwoWay}"  
                        AutoGenerateColumns="False" ItemsSource="{Binding Programs}" IsReadOnly="True">
            <data:DataGrid.Columns>
                <data:DataGridTextColumn Header="Name"  Binding="{Binding Path=Name}" Width="3*"></data:DataGridTextColumn>
                <data:DataGridTextColumn Header="Author" Binding="{Binding Path=Author}" Width="2*" ></data:DataGridTextColumn>
                <data:DataGridTextColumn Header="Date Creation" Binding="{Binding Path=DateCreation}" Width="3*"></data:DataGridTextColumn>       
            </data:DataGrid.Columns>
        </data:DataGrid>
    </Grid>
</UserControl>

And code for ProgramGrid.xaml.cs :

namespace DEV_CENTER
{
    public partial class ProgramGrid : UserControl
    {
        public ProgramGrid()
        {
            InitializeComponent();
            this.DataContext = AddButtonViewModel.getInstance();
        }

        private void OnClick(object sender, System.Windows.RoutedEventArgs e)
        {
            AddButton addProgramObj = new AddButton();  //Because AddButton is my xaml childwindow
            addProgramObj.Show();
        }
    }
}

And button code for AddButton.xaml and AddButton.cs has no problem (I mean all the data I am entering on form obtained on button click is visible on corresponding fields (Name, Author, etc.) on debugging).

AddButton.cs :

namespace DEV_CENTER
{
    public partial class AddButton : ChildWindow
    {
        public AddButton()
        {
            this.DataContext = AddButtonViewModel.getInstance();
            InitializeComponent();
        }        
    }
}

And AddButtonViewModel.cs is my View model class. I guess it has the problem.

namespace ViewModel
{
    public class AddButtonViewModel : GenericViewModel
    {
      private static AddButtonViewModel addbuttonviewModel;
      public static AddButtonViewModel getInstance()
       {
        if (addbuttonviewModel == null) addbuttonviewModel = new AddButtonViewModel();
        return addbuttonviewModel;
       }

        #region PROPERTIES
        private ObservableCollection<AddButtonViewModel> programs;   //Its obtained for binding from ProgramGrid.xaml
        public ObservableCollection<AddButtonViewModel> Programs
        {
            get { return this.programs; }
            set { this.programs = value; OnPropertyChanged("Programs"); }
        }

        private String name;
        public String Name
        {
            get { return name; }
            set { name = value; OnPropertyChanged("Name"); }
        }
        private String version;
        public String Version
        {
            get { return version; }
            set { version = value; OnPropertyChanged("Version"); }
        }
        private String author;
        public String Author
        {
            get { return author; }
            set { author = value; OnPropertyChanged("Author"); }
        }
        private String company;
        public String Company
        {
            get { return company; }
            set { company = value; OnPropertyChanged("Company"); }
        }
        private String dateCreation;
        public String DateCreation
        {
            get { return dateCreation; }
            set { dateCreation = value; OnPropertyChanged("DateCreation"); }
        }
        private String description;

        public String Description
        {
            get { return description; }
            set { description = value; OnPropertyChanged("Description"); }
        }

        private ICommand saveCmd; ITS for Save Button click after writing the data on form popuped.
        public ICommand SaveCmd
        {
            get { return saveCmd; }
            set { saveCmd = value; }
        }


        private ICommand cancelCmd;
        public ICommand CancelCmd
        {
            get { return cancelCmd; }
            set { cancelCmd = value; }
        }
        #endregion

         #region CONSTRUCTOR
        public AddButtonViewModel()
        {
                this.saveCmd = new DelegateCommand(SaveMetadata);
                this.cancelCmd = new DelegateCommand(CancelMetadata);         

        }
        #endregion


        #region method

        /*
         * save from Form
         */
        public void SaveMetadata(object param)  //i can see on debugging that i have all the fields thati have saved in form
        {            
            programs = new ObservableCollection<AddButtonViewModel>();
            AddButtonViewModel p1 = new AddButtonViewModel();
            p1.Name = Name;
            p1.Author = Author;
            p1.Company = Company;
            p1.Description = Description;
            p1.DateCreation = DateCreation;
            Programs.Add(p1);
        }

        /*
         * cancel modification action
         */
        public void CancelMetadata(object param)
        {
            initForm();
        }
        #endregion
    }
}

How to deal with my AddButtonViewModel.cs class so that I will be able to render the List (containing the data saved from Form) below Programs exactly the same way ?

In your code, you add the program to the underlying data structure ( programs ) instead of the property. You should add it to Programs in order for the setter to raise the OnPropertyChanged . Also, you will need to change your Programs property to be bound to your model's values ( ButtonProgram ).

public void SaveMetadata(object param) //i can see on debugging that i have all the fields thati have saved in form 
{ 
    ObservableCollection<ButtonProgram> newCollection = new 

    ObservableCollection<ButtonProgram>(programs.ToList()); 
    ButtonProgram p1 = new ButtonProgram(); 
    p1.Name = Name; 
    p1.Author = Author; 
    p1.Company = Company; 
    p1.Description = Description; 
    p1.DateCreation = DateCreation; 
    newCollection.Add(p1); 
    Programs = newCollection;
}

This change should tell your UI to update the list.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM