【问题标题】:Whats wrong with my MVVM approach here我的 MVVM 方法有什么问题
【发布时间】:2014-07-08 12:54:50
【问题描述】:

我正在尝试使用 silverlight-c# 实现 MVVM 方法(不使用 Galla 或 prism 或任何内置的东西)。

我必须做的: (我在第一个视图中有一个按钮,在该按钮下方有一个网格,它将用于很快显示一个列表)。当我按下一个按钮时,它会弹出一个表单,我在上面 将输入信息,该信息应该显示在“Programs图像1中的文本”下方区域的列表中

我所做的是:

我已成功创建按钮单击事件并读取用户从表单写入的数据。现在的问题是我无法在 **Programs 区域呈现用户从该表单读取的数据。

在这里你可以看到我有下面的区域程序,并且有:姓名、作者和创建日期等等。就在下面,我想在单击按钮(“添加程序”按钮)获得的表单上显示我要从用户那里读取的数据。

(“添加程序”是要点击的按钮) 点击我得到:

ProgramGrid.xaml 中用于绑定的代码

<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>

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();
        }
    }
}

AddButton.xaml 和 AddButton.cs 的按钮代码没有问题(我的意思是我在按钮单击时获得的表单上输入的所有数据在调试时的相应字段(名称、作者等)上可见)。

AddButton.cs :

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

AddButtonViewModel.cs 是我的视图模型类。 我猜是有问题。

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
    }
}

如何处理我的 AddButtonViewModel.cs 类,以便我能够以完全相同的方式呈现 Programs 下面的 List(包含从 Form 保存的数据)?

【问题讨论】:

    标签: c# .net wpf silverlight mvvm


    【解决方案1】:

    在您的代码中,您将程序添加到底层数据结构 (programs) 而不是属性。您应该将它添加到Programs,以便设置器提升OnPropertyChanged。此外,您需要更改 Programs 属性以绑定到模型的值 (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;
    }
    

    此更改应告诉您的 UI 更新列表。

    【讨论】:

    • 我做到了,但仍然没有更新任何东西。你观察到一件事吗?我的 ProgramGrid.xaml.cs 类 whse xaml 包含按钮和要在其上显示数据的网格。它不包含 DataContext。即使我执行“this.DataContext = AddButtonViewModel.getInstance();”在执行此 getInstance() 后我也会单击按钮。是因为这个吗?
    • 好吧,如果你不得不这样做,你会怎么做?从开始? (因为程序不是我改变它的问题,它还没有更新任何东西)
    • AddButton构造函数中,尝试在InitializeComponent之后设置DataContext...可能会被覆盖。
    • 我的 ProgramGrid.xaml 包含按钮和网格(数据将在其上显示)。它不包含绑定 ViewModel 类的 DataContext(参见那里)。但即使我执行“this.DataContext = AddButtonViewModel.getInstance(); there”,我也会在执行此 getInstance() 后单击按钮。是因为这个吗?
    • 我不是在谈论您的 ProgramGrid.xaml,在您向我们展示的代码中,AddButton 视图的构造函数包含您的 DataContext 的定义。
    猜你喜欢
    • 1970-01-01
    • 2014-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多