如何创建通用视图模型

时间:2014-05-16 13:45:40

标签: wpf entity-framework mvvm

我必须创建一个通用的viewmodel,它传递一对多关系的实体。 我将解释: 我的窗口:

<Window x:Class="Invoice_Example_Brux.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:invoiceExampleBrux="clr-namespace:Invoice_Example_Brux"
    Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
    <invoiceExampleBrux:MainWindowViewModel/>
</Window.DataContext>
<Grid>
    <TextBox HorizontalAlignment="Left" Height="23" Margin="174,78,0,0" TextWrapping="Wrap" Text="{Binding MyModel.Name}" VerticalAlignment="Top" Width="120"/>
    <Label Content="Id" HorizontalAlignment="Left" Margin="10,53,0,0" VerticalAlignment="Top"/>
    <TextBox HorizontalAlignment="Left" Height="23" Margin="10,78,0,0" TextWrapping="Wrap" Text="{Binding MyModel.Id}" VerticalAlignment="Top" Width="120"  IsReadOnly="True"/>
    <Label Content="Number" HorizontalAlignment="Left" Margin="322,52,0,0" VerticalAlignment="Top"/>
    <TextBox HorizontalAlignment="Left" Height="23" Margin="322,78,0,0" TextWrapping="Wrap" Text="{Binding MyModel.Number}" VerticalAlignment="Top" Width="120"/>
    <Label Content="Name" HorizontalAlignment="Left" Margin="174,53,0,0" VerticalAlignment="Top"/>
    <Button Content="Save" HorizontalAlignment="Left" Margin="211,288,0,0" VerticalAlignment="Top" Width="75" Command="{Binding SaveCommand}"/>
    <ComboBox
        SelectionChanged="Selector_OnSelectionChanged"
              HorizontalAlignment="Left" Margin="180,38,0,0" VerticalAlignment="Top" Width="120"                  
              DisplayMemberPath="Name"
              ItemsSource="{Binding DocumentType,UpdateSourceTrigger=PropertyChanged}"/>
    <Label Content="Type Document" HorizontalAlignment="Left" Margin="192,12,0,0" VerticalAlignment="Top"/>
</Grid>

myWindows codebheind:

   namespace Invoice_Example_Brux
{

    public partial class MainWindow
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Selector_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            var cmb  = sender as ComboBox;
            var selectedItem = cmb.SelectedValue as DocumentType;
            if (selectedItem == null) return;
            var code = selectedItem.Code;
            switch (code)
            {
                case "A":
                    DataContext = new ViewModelGeneric<DocumentA>();
                    break;
                case "B":
                    DataContext = new ViewModelGeneric<DocumentB>();
           break;
                case "C":
                    break;
            }
        }
    }
}

我的实体文件A和文件B:

 public class DocumentA : DocumentGeneral
    {
        public ObservableCollection<DetailDocumentA> DetailDocumentA { get; set; }

    }
   public class DetailDocumentA : DetailDocumentGeneral
    {
    }

  public class DocumentB : DocumentGeneral
    {
        public ObservableCollection<DetailDocumentB> DetailDocumentB { get; set; }

    }
   public class DetailDocumentB : DetailDocumentGeneral
    {
    }

    public class DocumentGeneral 
    {
        public Guid Id { get; set; }
        public string Name { get; set; }
        public string Number { get; set; }
        public string TypeDocument { get; set; }

    }
   public class DetailDocumentGeneral
    {
        public Guid Id { get; set; }
        public string Quantity { get; set; }
        public string Price { get; set; }
        public string Total { get; set; }
    }

我的ViewModelGeneric:

public class ViewModelGeneric<T> : ViewModelBase
        where T : DocumentGeneral, new()
    {
        public T MyModel { get; set; }
        public RelayCommand SaveCommand { get; set; }
        public ViewModelGeneric()
        {
            MyModel = new T();
            SaveCommand = new RelayCommand(Save);
        }

        private void Save(object obj)
        {
            if (MyModel.Id == Guid.Empty)
            {
                MyModel.Id = Guid.NewGuid();
            }
//the problme is here. how can I do to fill in the detail of my entity
          /*  MyModel.Detail.Add(new DetailDocumentGeneral
           {
               Price = "50",Quantity = "100",Total = "5000"
           });*/

            using (var ctx = new DocumentContext())
            {
                var document = ctx.Set<T>();
                document.Add(MyModel);
                ctx.SaveChanges();
            }
        }
    }

问题在于,根据我的组合框的选择,我必须选择不同的实体。 但我无法访问相应的detailDocument =(

1 个答案:

答案 0 :(得分:0)

请停止你正在做的事...... WPF是一种冗长的语言。这意味着您将不得不编写大量代码,甚至可能复制大型部分。请帮个忙,接受这个事实。我一次又一次地看到这种情况(当我第一次学习WPF时,甚至浪费了我自己的时间),但它总是以泪水结束。

在MVVM中,习惯上为一个视图提供一个视图模型。此视图模型负责提供相关视图的所有数据和功能。除非您的所有视图几乎相同,否则您的通用视图模型将无法工作。更糟糕的是,即使它确实有效,也会使你的项目变得更加复杂,并使简单的任务变得更加困难。

如果您确实不想每次都重写视图模型,那么只需从另一个视图模型中复制并粘贴,然后只需更改差异即可。说了这么多之后,我必须说你的代码似乎与你的话有些奇怪...你说你想要一个通用的视图模型,但你的问题与数据访问有关。

将数据访问类放在与视图模型不同的项目中更为常见。在这方面,似乎你正试图实施The Repository Pattern,但是在错误的地方。制作通用数据访问类比普通视图模型更常见,并且不会出错。

因此,我强烈建议您忘记通用视图模型并为每个视图声明一个新模型,然后将您的数据访问代码移动到一个单独的项目(或至少一个单独的类)中,并可选择将其设置为通用视图模型(使用MSDN上的链接页面获取帮助)。这个可能是你在这项努力中遇到的第一个真正的问题,但是如果你继续沿着这条路走下去,我可以向你保证它不会是最后一个。