将模型属性绑定到 DevExpress GridView






4.73/5 (5投票s)
将模型属性绑定到 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