从PRESENTATION层(MVVM)访问VIEW中的数据以获取datagrid itemssource

时间:2013-04-26 03:36:11

标签: c# wpf mvvm

在我的表示层(PrintViewModel.cs)中,我有以下代码,我将公开将用于填充数据网格的数据集。

    public const string ViewFullRecipeGroupingPropertyName = "ViewFullRecipeGrouping";
    public List<ViewFullRecipe> _viewFullRecipeGrouping = new List<ViewFullRecipe>();
    public List<ViewFullRecipe> ViewFullRecipeGrouping
    {
        get { return _viewFullRecipeGrouping; }
        set { Set(ViewFullRecipeGroupingPropertyName, ref _viewFullRecipeGrouping, value, true); }
    }

现在在我的视图层(PrintPage.xaml.cs)中我以编程方式创建数据网格,完成后我需要设置itemsource,如下所示:

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
    var datagrid = new DataGrid();
    datagrid.ItemsSource = PrintViewModel.ViewFullRecipeGrouping;
    }

然而,这会产生以下错误:
    非静态字段,方法或属性'Presentation.Print.PrintViewModel.ViewFullRecipeGrouping.get'

需要对象引用

我知道我的数据集没问题,因为如果我直接在XAML中设置它,它的工作完全正常(对于我在XAML中创建的测试数据网格)。

所以,我想问题是我如何从PRESENTATION图层(在我的VIEW图层中)访问ViewFullRecipeGrouping。

这是PrintViewModel实例化的方式:

public class ViewModelLocator
{
    static ViewModelLocator()
    {
        SimpleIoc.Default.Register<PrintViewModel>(true);
    }
    public PrintViewModel Print
    {
        get
        {
            return ServiceLocator.Current.GetInstance<PrintViewModel>();
        }
    }

关于如何获得这项工作或更好的方式的任何想法或建议(我是否违反MVVM?) 谢谢,

2 个答案:

答案 0 :(得分:1)

我相信您收到此错误的原因:

An object reference is required for the non-static field, method, or property 'Presentation.Print.PrintViewModel.ViewFullRecipeGrouping.get'

是因为您尝试访问property,就好像它是静态的一样。在不了解ViewModel类的情况下,类是静态的吗?如果不是,您尝试访问它的方式将无法工作..您将需要首先实例化该类,然后像这样访问该属性:(您可能还需要设置数据上下文)

  private PrintViewModel _viewModel = new PrintViewModel();
  private void Window_Loaded(object sender, RoutedEventArgs e)
  {
    this.DataContext = _viewModel;
    var datagrid = new DataGrid();
    datagrid.ItemsSource = _viewModel.ViewFullRecipeGrouping;
  }

我还想问一下,为什么要以编程方式创建DataGrid?为什么不通过XAML定义它,并使用DataBinding作为ItemsSource。

另外,我想指出,属性的重点是封装。您正在为公共成员变量使用“getter”。成员变量实际上应该是私有的:

private List<ViewFullRecipe> _viewFullRecipeGrouping = new List<ViewFullRecipe>();
public List<ViewFullRecipe> ViewFullRecipeGrouping
{
    get { return _viewFullRecipeGrouping; }
    set { Set(ViewFullRecipeGroupingPropertyName, ref _viewFullRecipeGrouping, value, true); }
}

修改 好的,既然您正在使用“工厂”来获得看起来像ViewModel的singelton实例,请将代码更新为:

  private ViewModelLocator _locator = new ViewModelLocator();
  private void Window_Loaded(object sender, RoutedEventArgs e)
  {
    var viewModel = _locator.Print; // your ViewModel instance
    var datagrid = new DataGrid();
    datagrid.ItemsSource = viewModel.ViewFullRecipeGrouping;
  }

或尝试设置GridView的DataBinding

  private ViewModelLocator _locator = new ViewModelLocator();
  private void Window_Loaded(object sender, RoutedEventArgs e)
  {
    var viewModel = _locator.Print; // your ViewModel instance
    this.DataContext = viewModel;

    var datagrid = new DataGrid();
    var binding = new Binding("ViewFullRecipeGrouping");
    BindingOperations.SetBinding(datagrid, DataGrid.ItemsSource, binding);
  }

答案 1 :(得分:0)

没有看到你的其余代码,我只能猜测,但看起来这个赋值代码包含在一个静态方法中。

public static void AssignSource() // I'm guessing at the name here.
{
    var datagrid = new DataGrid();
    //ViewFullRecipeGrouping is not static so will throw the exception.
    datagrid.ItemsSource = PrintViewModel.ViewFullRecipeGrouping;
}

如果是这种情况,则需要使赋值方法非静态(最可能最容易修复),将ViewFullRecipeGrouping属性放在自己的静态方法中,或者创建一个在赋值代码的上下文中的属性,即

public static void AssignSource() // I'm guessing at the name here.
{
    PrintViewModel.ViewFullRecipeGrouping = new List<ViewFullRecipe>();
    PrintViewModel.ViewFullRecipeGrouping.Add(new ViewFullRecipe());
    var datagrid = new DataGrid();
    datagrid.ItemsSource = PrintViewModel.ViewFullRecipeGrouping;
}