65.9K
CodeProject 正在变化。 阅读更多。
Home

将模型属性绑定到 DevExpress GridView

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.73/5 (5投票s)

2014年1月23日

CPOL

2分钟阅读

viewsIcon

34174

将模型属性绑定到 DevExpress GridView

引言

厌倦了通过添加带有属性名称的列来定义您的 DevExpress 网格吗?

那从资源中设置列标题呢?

我构建了一个泛型(类型化)GridViewSetting ,让您可以像这样将列绑定到模型

@model IEnumerable<Model>
@{
 Html.DevExpress()
   .GridView<Model>(settings =>
   {
      settings.Name = "gridView";
      settings
         .GetColumns()
         .Bound(model => model.Field1)
         .Bound(model => model.Field2)
         .Bound(model => model.Field3)
         .Bound(model => model.Amount, column => column
                                                       .PropertiesEdit
                                                       .DisplayFormatString = "N")
         .Bound(model => model.Ratio, column => column
                                                      .PropertiesEdit
                                                      .DisplayFormatString = "P")
         .Bound(model => model.Date, column => column
                                                     .PropertiesEdit
                                                     .DisplayFormatString = "yyyy-MM-dd");
   })
   .Bind(Model)
   .GetHtml();
}

Using the Code

让我们从这个上下文开始。

一个模型

public class Person
{
    public int Id { get; set; }
    [Display(Description = "First Name" )]
    public string FirstName { get; set; }
 
    [Display(Description = "Last Name" )]
    public string LastName { get; set; }
 
    [Display(Description = "Function" )]
    public string Function { get; set; }
 
    [Display(Description = "Hiring Date" )]
    public DateTime HiringDate { get; set; }
}

一个控制器动作

public ActionResult Index()
{
    var persons = new Collection<Person>
                  {
                      new Person
                      {
                          Id = 1,
                          FirstName = "Bill",
                          LastName = "Telnor",
                          Function = "Sales Rep",
                          HiringDate = new DateTime(2011, 5, 13)
                      },
                      new Person
                      {
                          Id = 2,
                          FirstName = "Joe",
                          LastName = "Bean",
                          Function = "Home Officer",
                          HiringDate = new DateTime(1999, 12, 2)
                      },
                      new Person
                      {
                          Id = 3,
                          FirstName = "Stan",
                          LastName = "Greenspan",
                          Function = "Horticulturist",
                          HiringDate = new DateTime(2008, 3, 28)
                      },
                  };
    return View(persons);
}

以及一个视图

@using System.Web.UI.WebControls
@using GridViewExtensionWebSite.Models
@model IEnumerable<Person>

@{
    Html.DevExpress()
        .GridView(settings =>
                  {
                      settings .Name = "gridPerson";
                      settings .Width = Unit.Percentage(100);
                      settings .Height = Unit.Percentage(100);
                      settings 
                          .Columns
                          .Add("FirstName", "First Name");
                      settings 
                          .Columns
                          .Add("LastName", "Last Name");
                      settings 
                          .Columns
                          .Add("Function", "Function");
                      settings 
                          .Columns
                          .Add("HiringDate", "Hiring Date", 
                               MVCxGridViewColumnType.DateEdit);
                  })
        .Bind(Model)
        .GetHtml();
}

首先,原始的 Html.DevExpress().GridView 方法接收一个参数 Action<DevExpress.Web.Mvc.GridViewSettings>。然后我们必须从这个类继承以使其成为泛型。我将所有类放在 DevExpress.Web.Mvc 命名空间中以使其更简单。

namespace DevExpress.Web.Mvc
{
    public class GridViewSettings<TModel> : GridViewSettings
    {
        #region Methods

         //We will add methods here later.  Let's just see what happens now.
        #endregion
    }
}

现在,我们可以将一个扩展方法添加到 DevExpress.Web.Mvc.UI.ExtensionsFactory 类。将添加泛型 GridView<TModel> 方法,但我们首先需要接收视图上下文来初始化 GridViewExtension。DevExpress 具有内部方法来设置和获取当前视图上下文。我们可以进行一些代码反射或创建我们自己的 ExtensionsFactory,但为什么不保持简单并将视图上下文作为参数传递给 GridView 方法呢?

现在,让我们基本上通过实例化我们自己的类型化 GridViewSettings<TModel> 来重现与 DevExpress 相同的功能。将其传递给委托并返回一个 new GridViewExtension

using System;
using DevExpress.Web.Mvc.UI;
namespace DevExpress.Web.Mvc
{
    public static class GridViewExtensions
    {
        public static GridViewExtension GridView<TModel>(
                      this ExtensionsFactory extensionsFactory,
                      ViewContext viewContext,
                      Action<GridViewSettings<TModel>> action)
        {
            var gridViewSettings = new GridViewSettings<TModel>();
            action(gridViewSettings);
            return new GridViewExtension(gridViewSettings, viewContext);
        }
    }
}

就这些了吗?还没有。我们将修改我们的视图…

@{
    Html.DevExpress()
        .GridView<Person>(Html.ViewContext, gridViewSettings =>
                  {
                      …
                  })
        .Bind(Model)
        .GetHtml();
}

如果在 Visual Studio 中将光标悬停在 GridViewSettings 变量上,我们会看到它的类型现在是 GridViewSettings<Person>。很好,但这能给我们什么?什么也没有!

我们需要用更有效的东西替换 GridViewSettings.Column 属性的使用。GridViewSettings.Column 返回一个 MVCxGridViewColumnCollection,我们的 GridViewSettings<TModel> 将返回一个 MVCxGridViewColumnCollection<TModel>

我们需要什么方法来管理列?我们的需求很简单;我们需要将一列绑定到模型的属性,一个绑定到属性并编辑列属性,以及另一个添加计算的、静态的、操作或其他类型的列。

顺便说一句,为什么不使其流畅...

using System;
using System.Linq.Expressions;
using System.Web.Mvc;
using DevExpress.Utils;

namespace DevExpress.Web.Mvc
{
    public class MVCxGridViewColumnCollection<TModel>
    {
        #region Ctors

        public MVCxGridViewColumnCollection(MVCxGridViewColumnCollection columns)
        {
            ColumnCollection = columns;
        }

        #endregion

        #region Properties

        public MVCxGridViewColumnCollection ColumnCollection { get; private set; }

        #endregion

        #region Methods

        public MVCxGridViewColumnCollection<TModel> Bound<TValue>(
                                            Expression<Func<TModel, TValue>> expression, 
                                            Action<MVCxGridViewColumn> setColumn)
        {
            if (expression == null)
                throw new ArgumentNullException("expression");

            setColumn(GetNewColumn(expression));
            return this;
        }

        public MVCxGridViewColumnCollection<TModel> Bound<TValue>(
                                            Expression<Func<TModel, TValue>> expression)
        {
            if (expression == null)
                throw new ArgumentNullException("expression");

            GetNewColumn(expression);

            return this;
        }

        public MVCxGridViewColumnCollection<TModel> Add(Action<MVCxGridViewColumn> setColumn)
        {
            //Add a basic MVCxGridViewColumn.
            var gridViewColumn = ColumnCollection.Add();
            setColumn(gridViewColumn);
            return this;
        }

        private MVCxGridViewColumn GetNewColumn<TValue>(
                                            Expression<Func<TModel, TValue>> expression)
        {
            //Add a basic MVCxGridViewColumn reproduce sensibly what MVC does 
            //in DisplayFor<TMember> method.
            var metaData = ModelMetadata.FromLambdaExpression(expression, 
                                                           new ViewDataDictionary<TModel>());
            var gridViewColumn = ColumnCollection.Add();
            gridViewColumn.Caption = metaData.DisplayName;
            gridViewColumn.FieldName = metaData.PropertyName;
            gridViewColumn.HeaderStyle.Wrap = DefaultBoolean.True;
            return gridViewColumn;
        }

        #endregion
    }
}

现在,让我们更改我们的 GridViewSettings<TModel> 并添加一个方法来获取列集合。

namespace DevExpress.Web.Mvc
{
    public class GridViewSettings<TModel> : GridViewSettings
    {
        #region Methods

        public MVCxGridViewColumnCollection<TModel> GetColumns()
        {
            return new MVCxGridViewColumnCollection<TModel>(Columns);
        }

        #endregion
    }
}

现在,我们可以用我们的新方法 GetColumns 替换视图中 GridViewSettings Columns 属性的使用。

@model IEnumerable<Person>
@{
 Html.DevExpress()
     .GridView<Person>(Html.ViewContext , settings =>
     {
        settings.Name = "gridPerson";
        settings.Width = Unit.Percentage(100);
        settings.Height = Unit.Percentage(100);
        settings.GetColumns()
                .Bound(model => model.FirstName)
                .Bound(model => model.LastName)
                .Bound(model => model.Function)
                .Bound(model => model.HiringDate, 
                                column => column.PropertiesEdit
                                                .DisplayFormatString = "yyyy-MM-dd");
     })
     .Bind(Model)
     .GetHtml();
}

完成了!

在源代码中,我还添加了代码将模型绑定到带列(多行标题)。

我希望您能理解,我没有使用 bootstraper、视图模型、存储库以及其他最佳实践来创建此演示。我想向您展示一个 DevExpress 扩展,而不是一个完整的解决方案!

谢谢。

历史

  • 创建于 2013-01-23
© . All rights reserved.