e.GetListSourceFieldValue在CustomUnboundColumnData事件处理程序中返回null [英] e.GetListSourceFieldValue returns null in the CustomUnboundColumnData event handler

查看:378
本文介绍了e.GetListSourceFieldValue在CustomUnboundColumnData事件处理程序中返回null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在ASP.NET MVC 4项目中使用DevExpress控件。



我在 GridView ASP.NET MVC的扩展。在 CustomUnboundColumnData 事件处理程序中, e.GetListSourceFieldValue 总是为我返回null。



然后,我尝试从模型中直接获取值,而不是调用此方法(请参阅方法调用之上的注释行),但即使有效,也会产生副作用不会刚刚进入。



我正在使用ASP.NET MVC 4与Visual Web Developer Express 2010版。我正在使用DevExpress扩展MVC v12.2.10.0。



我的操作系统是Windows 7,64位。但是,我使用的扩展只有32位。



我无法将我的整个解决方案分解成多个项目,其中大多数都有很多IP我为我的客户写的代码但是这里是我代码中的相关内容。



Index.cshtml(Razor View Engine)
---------- -------------------------------------------------- -------

  @model List< GlobalizationUI.Presentation.ViewModels.StringTableRow> 

@ {
ViewBag.Title =Strings;
}

< div id =pageCaption>字符串< / div>

@ Html.Partial(_ StringsPartial,Model)

_StringsPartial.cshtml(Razor View Engine)
------------------------------------- ------------------------------

  @using System.Web.UI.WebControls; 
@using System.Data;
@model List< GlobalizationUI.Presentation.ViewModels.StringTableRow>

@ Html.DevExpress()。GridView(settings =>
{
settings.Name =gvStrings;

settings.CallbackRouteValues =新的{Controller =Strings,Action =StringsPartial};

settings.Width = 1200;

settings.SettingsPager.Position = PagerPosition.TopAndBottom;
settings.SettingsPager.FirstPageButton.Visible = true;
settings.SettingsPager.LastPageButton.Visible = true;
settings.SettingsPager.PageSizeItemSettings.Visible = true;
settings.SettingsPager.PageSizeItemSettings.Items = new string [] {10,20,50,100,200};
settings.SettingsPager.PageSize = 50;

settings.Settings .ShowFilterRow = true;
settings.Settings.ShowFilterRowMenu = true;

settings.CommandColumn.Visible = true;
settings.CommandColumn.ClearFilterButton.Visible = true;

settings.Settings.ShowHea derFilterButton = true;

settings.KeyFieldName =ResourceKeyId;

settings.Columns.Add(Key);

var categoryColumn = settings.Columns.Add(CategoryId,Category);
categoryColumn.ColumnType = MVCxGridViewColumnType.ComboBox;
var categoryColumnEditProperties = categoryColumn.PropertiesEdit为ComboBoxProperties;
categoryColumnEditProperties.DataSource = ViewBag.AllCategories;
categoryColumnEditProperties.TextField =Name;
categoryColumnEditProperties.ValueField =Id;
categoryColumnEditProperties.ValueType = typeof(long);

如果(Model!= null&& Model.Count> 0&&$&
模型[0]!= null&&&&Model&[0] .StringValues! = null&&&Model [0] .StringValues.Count> 0)
{
foreach(var kvp in Model [0] .StringValues)
{
settings。 Columns.Add(col =>
{
col.FieldName = kvp.CultureShortName;
col.Caption = kvp.CultureShortName;
col.UnboundType = DevExpress.Data.UnboundColumnType .Object;
col.SetDataItemTemplateContent(container => {ViewContext.Writer.Write(DataBinder.Eval(container.DataItem,col.FieldName +.StringValue));});

col.SetEditItemTemplateContent(container =>
{
Html.DevExpress()。TextBox(s =>
{
s.Name = string.Format(txt {0},kvp.CultureShortName);
})。Bind(kvp.StringValue).Render();
});
});
}
}

settings.CustomUnboundColumnData =(sender,e)=>
{
var fixedColumns = new List< string> {ResourceKeyId,Key,CategoryId};

if(!fixedColumns.Contains(e.Column.FieldName))
{
if(e.IsGetData)
{
try
{
// var values = Model [e.ListSourceRowIndex] .StringValues;

var values = e.GetListSourceFieldValue(e.ListSourceRowIndex,StringValues)作为IList< GlobalizationUI.Presentation.ViewModels.CultureNameAndStringValue> ;;

if(values!= null)
{
var value = values.FirstOrDefault(pair => pair.CultureShortName == e.Column.FieldName);

var defaultValue = default(GlobalizationUI.Presentation.ViewModels.CultureNameAndStringValue);

e.Value = value.Equals(defaultValue)? defaultValue:new GlobalizationUI.Presentation.ViewModels.CultureNameAndStringValue();
}
}
catch(Exception ex)
{
System.Diagnostics.Debugger.Break();
System.Diagnostics.Debug.Print(ex.ToString());
}
}
}
};

foreach(settings.Columns中的GridViewDataColumn列)
{
column.Settings.HeaderFilterMode = HeaderFilterMode.CheckedList;
}

settings.SettingsEditing.AddNewRowRouteValues = new {Controller =Strings,Action =CreateNew};
settings.SettingsEditing.UpdateRowRouteValues = new {Controller =Strings,Action =Edit};
settings.SettingsEditing.DeleteRowRouteValues = new {Controller =Strings,Action =Delete};

settings.SettingsEditing.Mode = GridViewEditingMode.Inline;

settings.SettingsBehavior.ConfirmDelete = true;

settings.CommandColumn.Visible = true;
settings.CommandColumn.NewButton.Visible = true;
settings.CommandColumn.EditButton.Visible = true;
settings.CommandColumn.UpdateButton.Visible = true;
settings.CommandColumn.DeleteButton.Visible = true;

})。绑定(模型).GetHtml()

StringsController
-------------------------------------------- -----------------------

 使用System.Data; 
使用System.Web.Mvc;
使用GlobalizationUI.BusinessObjects;
使用Resources.BaseServices.Caching;
使用System.Collections.Generic;
使用System.ComponentModel;
使用GlobalizationUI.Presentation.ViewModels;
using Resources.Util;

命名空间GlobalizationUI.Presentation.Controllers
{
public class StringsController:Controller
{
private static string CacheKey_StringTable =CacheKey_StringTable;
private static string CacheKey_AllCategories =CacheKey_AllCategories;
private static object padLock = new object();

public ActionResult Index()
{
var stringTable = GetStringTable();

ViewBag.AllCategories = GetCategoryList();

return View(stringTable);
}

public ActionResult StringsPartial()
{
var stringTable = GetStringTable();

ViewBag.AllCategories = GetCategoryList();

返回PartialView(_ StringsPartial,stringTable);
}

[HttpPost]
public ActionResult CreateNew(StringTableRow row)
{
System.Diagnostics.Debugger.Break();

foreach(TypeDescriptor.GetProperties(row)中的PropertyDescriptor prop)
{
System.Diagnostics.Debug.Print(prop.Name);
}

返回内容(Hello,there!);
}

[HttpPost]
public ActionResult Edit(DataRow row)
{
return new EmptyResult();
}

[HttpPost]
public ActionResult删除(long resourceKeyId)
{
返回新的EmptyResult();
}

private IEnumerable< Category> GetCategoryList()
{
lock(padLock)
{
if(CacheManager.Contains(CacheKey_AllCategories))
{
返回CacheManager.Get< IEnumerable<类别>>(CacheKey_AllCategories);
}
}

var list = Category.All;

lock(padLock)
{
CacheManager.Add(CacheKey_AllCategories,list);
}

返回列表;
}

private List< StringTableRow> GetStringTable()
{
列表< StringTableRow> STRINGTABLE;

lock(padLock)
{
if(CacheManager.Contains(CacheKey_StringTable))
{
返回CacheManager.Get< List< StringTableRow>> (CacheKey_StringTable);
}
}

stringTable = new StringTable()。ToListOfStringTableRows();

lock(padLock)
{
CacheManager.Add(CacheKey_StringTable,stringTable);
}

return stringTable;
}
}
}

查看模型
----------------------------------------------- --------------------

 使用系统.Collections.Generic; 

命名空间GlobalizationUI.Presentation.ViewModels
{
public class StringTableRow
{
public long ResourceKeyId {get;组; }

public string Key {get;组; }

public long CategoryId {get;组; }

public List< CultureNameAndStringValue> StringValues {get;组;

}

命名空间GlobalizationUI.Presentation.ViewModels
{
public class CultureNameAndStringValue
{
public CultureNameAndStringValue() :this(null,null){}

public CultureNameAndStringValue(string cultureShortName,string stringValue)
{
CultureShortName = cultureShortName;

StringValue = stringValue;
}

public string CultureShortName {get;组; }

public string StringValue {get;组;
}
}

型号:
- -------------------------------------------------- ----------------

 使用System.Data; 
使用GlobalizationUI.Data;

命名空间GlobalizationUI.BusinessObjects
{
public class StringTable:DataTable
{
public StringTable()
{
var sql = @
declare @stmt nvarchar(max)

select @stmt =
isnull(@stmt +',','')+
'max的情况下,s.CultureId ='+ cast(c.Id为nvarchar(max))+
'then s.ResourceValue end)as'+ quotename(c.ShortName)
从文化为c
其中c.Supported = 1

选择@stmt ='
选择
rk.Id AS ResourceKeyId,
rk.Name AS [Key],
c.Id AS CategoryId,
c.Name作为CategoryName,'+ @stmt +'
从StringCategory as sc
LEFT OUTER将类别作为c添加到c.Id = sc.CategoryId
RIGHT OUTER JOIN ResourceKey as rk on rk.Id = sc.ResourceKeyId
inner join Strings as s on s.ResourceKeyId = rk.Id
group by rk.Id,rk.Name,c.Id,c .Name
'

exec sp_executesql @stmt = @stmt;;

this.Merge(Database.DefaultDatabase.GetDataTable(sql));
}
}
}

要查看的模型模型转换:
------------------------------------------- ------------------------

 使用系统; 
使用System.Collections.Generic;
使用System.Linq;
使用System.Web;
使用System.Data;
使用System.Data.SqlTypes;

命名空间GlobalizationUI.Presentation.ViewModels
{
public static class DataTableExtensions
{
public static List< StringTableRow> ToListOfStringTableRows(这个DataTable数据表)
{
var ret = new List< StringTableRow>();

if(dataTable == null || dataTable.Rows.Count == 0)return ret;

foreach(dataTable.Rows的DataRow行)
{
StringTableRow stringTableRow = new StringTableRow();

foreach(dataTable.Columns中的DataColumn列)
{
if(string.Compare(column.ColumnName,ResourceKeyId,true)== 0)
{
stringTableRow.ResourceKeyId =(long)row [column.ColumnName];
}
else if(string.Compare(column.ColumnName,Key,true)== 0)
{
stringTableRow.Key =(string)row [column。的ColumnName];
}
else if(string.Compare(column.ColumnName,CategoryId,true)== 0)
{
var categoryId = row [column.ColumnName];

stringTableRow.CategoryId = categoryId == DBNull.Value? 0:(long)categoryId;
}
else if(string.Compare(column.ColumnName,CategoryName,true)== 0)
{
continue;
}
else
{
if(stringTableRow.StringValues == null)
stringTableRow.StringValues = new List< CultureNameAndStringValue>();

stringTableRow.StringValues.Add(new CultureNameAndStringValue(column.ColumnName,(string)row [column.ColumnName]));
}
}

ret.Add(stringTableRow);
}

return ret;
}
}
}



用户界面应该看起来像图片如上图所示。 SQL查询返回的列数根据特定安装/部署/业务客户端支持的文化数量而有所不同。因此,需要使用未绑定的列。



我把这张照片没有通过这个代码,但是当我将数据直接绑定到一个 System.Data.DataTable ,并没有使用任何未绑定的列。直到我必须在MVC /服务器端的操作中编辑数据,这一切都很好。所以,我从使用 DataTable 转换为POCO,并对所有文化使用未绑定的列。



请帮助。

解决方案

好吧,虽然我只在两个小时前发布了这个问题,并且一直在尝试各种方法来解决这个问题。



刚才,我做的一件事情就是消除了这个问题。如果您将ASP.NET MVC的DevExpress GridViewExtension 绑定到像我这样的自定义POCO,那么它就是这样。



并且POCO有一个或多个成员是任何类型的集合,那么您必须和绝对必须初始化表示您的POCO的构造函数中的集合的属性。



例如,在我的例子中,模型是 StringTableRow 的列表,其中 StringTableRow 是一个POCO。



StringTableRow 类中,我有一个属性名为 StringValues ,其类型为 IList< CultureNameAndStringValue> ,它是一个集合。因此,为了让我的代码工作,我在我的 StringTableRow 类的结构中初始化了 StringValues 属性,一切都开始工作。

  using System.Collections.Generic; 

命名空间GlobalizationUI.Presentation.ViewModels
{
public class StringTableRow
{
public StringTableRow()
{
//我添加了这个ctor并初始化了
// StringValues属性和破坏的
//自定义绑定到未绑定的列
//开始工作。
StringValues = new List< CultureNameAndStringValue>();
}

public long ResourceKeyId {get;组; }

public string Key {get;组; }

public long CategoryId {get;组; }

public IList< CultureNameAndStringValue> StringValues {get;组; }
}
}


I am using DevExpress control within an ASP.NET MVC 4 project.

I am using unbound columns in the GridView extension for ASP.NET MVC. In the CustomUnboundColumnData event handler, the e.GetListSourceFieldValue always returns null for me.

I then tried getting the value directly from the model instead of calling this method (please see the commented line just above the call to the method) but even though that worked, it had side-effects, which I won't get into just now.

I am using ASP.NET MVC 4 with Visual Web Developer Express 2010 edition. I am using DevExpress extensions for MVC v12.2.10.0.

My OS is Windows 7, 64-bit. However, the extensions I am using are 32-bit only.

I cannot ship my whole solution as it is broken down into multiple projects, most of which have lots of IP code I've written for my client. But here are the relevant pieces from my code.

Index.cshtml (Razor View Engine) -------------------------------------------------------------------

@model List<GlobalizationUI.Presentation.ViewModels.StringTableRow>

@{
    ViewBag.Title = "Strings";
}

<div id = "pageCaption">Strings</div>

@Html.Partial("_StringsPartial", Model)

_StringsPartial.cshtml (Razor View Engine) -------------------------------------------------------------------

@using System.Web.UI.WebControls;
@using System.Data;
@model List<GlobalizationUI.Presentation.ViewModels.StringTableRow>

@Html.DevExpress().GridView(settings =>
    {
        settings.Name = "gvStrings";

        settings.CallbackRouteValues = new { Controller = "Strings", Action = "StringsPartial" };

        settings.Width = 1200;

        settings.SettingsPager.Position = PagerPosition.TopAndBottom;
        settings.SettingsPager.FirstPageButton.Visible = true;
        settings.SettingsPager.LastPageButton.Visible = true;
        settings.SettingsPager.PageSizeItemSettings.Visible = true;
        settings.SettingsPager.PageSizeItemSettings.Items = new string[] { "10", "20", "50", "100", "200" };
        settings.SettingsPager.PageSize = 50;

        settings.Settings.ShowFilterRow = true;
        settings.Settings.ShowFilterRowMenu = true;

        settings.CommandColumn.Visible = true;
        settings.CommandColumn.ClearFilterButton.Visible = true;

        settings.Settings.ShowHeaderFilterButton = true;

        settings.KeyFieldName = "ResourceKeyId";

        settings.Columns.Add("Key");

        var categoryColumn = settings.Columns.Add("CategoryId", "Category");
        categoryColumn.ColumnType = MVCxGridViewColumnType.ComboBox;
        var categoryColumnEditProperties = categoryColumn.PropertiesEdit as ComboBoxProperties;
        categoryColumnEditProperties.DataSource = ViewBag.AllCategories;
        categoryColumnEditProperties.TextField = "Name";
        categoryColumnEditProperties.ValueField = "Id";
        categoryColumnEditProperties.ValueType = typeof(long);

        if (Model != null && Model.Count > 0 &&
            Model[0] != null && Model[0].StringValues != null && Model[0].StringValues.Count > 0)
        {
            foreach (var kvp in Model[0].StringValues)
            {
                settings.Columns.Add(col =>
                {
                    col.FieldName = kvp.CultureShortName;
                    col.Caption = kvp.CultureShortName;
                    col.UnboundType = DevExpress.Data.UnboundColumnType.Object;
                    col.SetDataItemTemplateContent(container => { ViewContext.Writer.Write(DataBinder.Eval(container.DataItem, col.FieldName + ".StringValue")); });

                    col.SetEditItemTemplateContent(container =>
                        {
                            Html.DevExpress().TextBox(s =>
                                {
                                    s.Name = string.Format("txt{0}", kvp.CultureShortName);
                                }).Bind(kvp.StringValue).Render();
                        });
                });
            }
        }

        settings.CustomUnboundColumnData = (sender, e) =>
        {
            var fixedColumns = new List<string> { "ResourceKeyId", "Key", "CategoryId" };

            if (!fixedColumns.Contains(e.Column.FieldName))
            {
                if (e.IsGetData)
                {
                    try
                    {
                        // var values = Model[e.ListSourceRowIndex].StringValues;

                        var values = e.GetListSourceFieldValue(e.ListSourceRowIndex, "StringValues") as IList<GlobalizationUI.Presentation.ViewModels.CultureNameAndStringValue>;

                        if (values != null)
                        {
                            var value = values.FirstOrDefault(pair => pair.CultureShortName == e.Column.FieldName);

                            var defaultValue = default(GlobalizationUI.Presentation.ViewModels.CultureNameAndStringValue);

                            e.Value = value.Equals(defaultValue) ? defaultValue : new GlobalizationUI.Presentation.ViewModels.CultureNameAndStringValue();
                        }
                    }
                    catch (Exception ex)
                    {
                        System.Diagnostics.Debugger.Break();
                        System.Diagnostics.Debug.Print(ex.ToString());
                    }
                }
            }
        };

        foreach (GridViewDataColumn column in settings.Columns)
        {
            column.Settings.HeaderFilterMode = HeaderFilterMode.CheckedList;
        }

        settings.SettingsEditing.AddNewRowRouteValues = new { Controller = "Strings", Action = "CreateNew" };
        settings.SettingsEditing.UpdateRowRouteValues = new { Controller = "Strings", Action = "Edit" };
        settings.SettingsEditing.DeleteRowRouteValues = new { Controller = "Strings", Action = "Delete" };

        settings.SettingsEditing.Mode = GridViewEditingMode.Inline;

        settings.SettingsBehavior.ConfirmDelete = true;

        settings.CommandColumn.Visible = true;
        settings.CommandColumn.NewButton.Visible = true;
        settings.CommandColumn.EditButton.Visible = true;
        settings.CommandColumn.UpdateButton.Visible = true;
        settings.CommandColumn.DeleteButton.Visible = true;

    }).Bind(Model).GetHtml()

StringsController -------------------------------------------------------------------

using System.Data;
using System.Web.Mvc;
using GlobalizationUI.BusinessObjects;
using Resources.BaseServices.Caching;
using System.Collections.Generic;
using System.ComponentModel;
using GlobalizationUI.Presentation.ViewModels;
using Resources.Util;

namespace GlobalizationUI.Presentation.Controllers
{
    public class StringsController : Controller
    {
        private static string CacheKey_StringTable = "CacheKey_StringTable";
        private static string CacheKey_AllCategories = "CacheKey_AllCategories";
        private static object padLock = new object();

        public ActionResult Index()
        {
            var stringTable = GetStringTable();

            ViewBag.AllCategories = GetCategoryList();

            return View(stringTable);
        }

        public ActionResult StringsPartial()
        {
            var stringTable = GetStringTable();

            ViewBag.AllCategories = GetCategoryList();

            return PartialView("_StringsPartial", stringTable);
        }

        [HttpPost]
        public ActionResult CreateNew(StringTableRow row)
        {
            System.Diagnostics.Debugger.Break();

            foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(row))
            {
                System.Diagnostics.Debug.Print(prop.Name);
            }

            return Content("Hello, there!");
        }

        [HttpPost]
        public ActionResult Edit(DataRow row)
        {
            return new EmptyResult();
        }

        [HttpPost]
        public ActionResult Delete(long resourceKeyId)
        {
            return new EmptyResult();
        }

        private IEnumerable<Category> GetCategoryList()
        {
            lock (padLock)
            {
                if (CacheManager.Contains(CacheKey_AllCategories))
                {
                    return CacheManager.Get<IEnumerable<Category>>(CacheKey_AllCategories);
                }
            }

            var list = Category.All;

            lock (padLock)
            {
                CacheManager.Add(CacheKey_AllCategories, list);
            }

            return list;
        }

        private List<StringTableRow> GetStringTable()
        {
            List<StringTableRow> stringTable;

            lock (padLock)
            {
                if (CacheManager.Contains(CacheKey_StringTable))
                {
                    return CacheManager.Get<List<StringTableRow>>(CacheKey_StringTable);
                }
            }

            stringTable = new StringTable().ToListOfStringTableRows();

            lock (padLock)
            {
                CacheManager.Add(CacheKey_StringTable, stringTable);
            }

            return stringTable;
        }
    }
}

View Models -------------------------------------------------------------------

using System.Collections.Generic;

namespace GlobalizationUI.Presentation.ViewModels
{
    public class StringTableRow
    {
        public long ResourceKeyId { get; set; }

        public string Key { get; set; }

        public long CategoryId { get; set; }

        public List<CultureNameAndStringValue> StringValues { get; set; }
    }
}

namespace GlobalizationUI.Presentation.ViewModels
{
    public class CultureNameAndStringValue
    {
        public CultureNameAndStringValue() : this(null, null) { }

        public CultureNameAndStringValue(string cultureShortName, string stringValue)
        {
            CultureShortName = cultureShortName;

            StringValue = stringValue;
        }

        public string CultureShortName { get; set; }

        public string StringValue { get; set; }
    }
}

Model: -------------------------------------------------------------------

using System.Data;
using GlobalizationUI.Data;

namespace GlobalizationUI.BusinessObjects
{
    public class StringTable : DataTable
    {
        public StringTable()
        {
            var sql = @"
            declare @stmt nvarchar(max)

            select @stmt =
                isnull(@stmt + ', ', '') +
                'max(case when s.CultureId = ' + cast(c.Id as nvarchar(max)) +
                ' then s.ResourceValue end) as ' + quotename(c.ShortName)
            from Culture as c
            where c.Supported = 1

            select @stmt = '
                select
                    rk.Id AS ResourceKeyId,
                    rk.Name AS [Key],
                    c.Id AS CategoryId,
                    c.Name as CategoryName, ' + @stmt + '
                from StringCategory as sc
                    LEFT OUTER join Category as c on c.Id = sc.CategoryId
                    RIGHT OUTER JOIN ResourceKey as rk on rk.Id = sc.ResourceKeyId
                    inner join Strings as s on s.ResourceKeyId = rk.Id
                group by rk.Id, rk.Name, c.Id, c.Name
                '

            exec sp_executesql @stmt = @stmt;";

            this.Merge(Database.DefaultDatabase.GetDataTable(sql));
        }
    }
}

Model to View Model conversion: -------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Data.SqlTypes;

namespace GlobalizationUI.Presentation.ViewModels
{
    public static class DataTableExtensions
    {
        public static List<StringTableRow> ToListOfStringTableRows(this DataTable dataTable)
        {
            var ret = new List<StringTableRow>();

            if (dataTable == null || dataTable.Rows.Count == 0) return ret;

            foreach (DataRow row in dataTable.Rows)
            {
                StringTableRow stringTableRow = new StringTableRow();

                foreach (DataColumn column in dataTable.Columns)
                {
                    if (string.Compare(column.ColumnName, "ResourceKeyId", true) == 0)
                    {
                        stringTableRow.ResourceKeyId = (long)row[column.ColumnName];
                    }
                    else if (string.Compare(column.ColumnName, "Key", true) == 0)
                    {
                        stringTableRow.Key = (string)row[column.ColumnName];
                    }
                    else if (string.Compare(column.ColumnName, "CategoryId", true) == 0)
                    {
                        var categoryId = row[column.ColumnName];

                        stringTableRow.CategoryId = categoryId == DBNull.Value ? 0 : (long)categoryId;
                    }
                    else if (string.Compare(column.ColumnName, "CategoryName", true) == 0)
                    {
                        continue;
                    }
                    else
                    {
                        if (stringTableRow.StringValues == null)
                            stringTableRow.StringValues = new List<CultureNameAndStringValue>();

                        stringTableRow.StringValues.Add(new CultureNameAndStringValue(column.ColumnName, (string)row[column.ColumnName]));
                    }
                }

                ret.Add(stringTableRow);
            }

            return ret;
        }
    }
}

The user interface is supposed to look somewhat like the the picture shown above. The number of columns returned by the SQL query is variable depending upon the number of cultures supported by a particular installation/deployment/business client. Hence the need for using unbound columns.

I took this picture not through this code but through an older version of my code when I bound data directly to a System.Data.DataTable and did not use any unbound columns. That was all well until I had to edit the data in the actions at the MVC/server side. So, I switched from using a DataTable to a POCO and used unbound columns for all cultures.

Kindly help.

解决方案

Okay, though I posted this question only 2 hours or so ago, I've had this trouble for over 8 hours now and have been trying various ways to solve this problem.

And just now, one of the things I did made this problem go away. Here it is.

If you are binding your DevExpress GridViewExtension for ASP.NET MVC to a custom POCO like mine, and that POCO has one or more members that are collections of any kind, then, you must and absolutely must initialize those properties that represent collections in the constructor of your POCO.

For e.g., in my case, the model was a list of StringTableRow's, where StringTableRow was a POCO.

In the StringTableRow class, I had a property named StringValues which was of type IList<CultureNameAndStringValue>, which is a collection. Therefore, for my code to work, I initialized the StringValues property in the construct of my StringTableRow class and everything started to work.

using System.Collections.Generic;

namespace GlobalizationUI.Presentation.ViewModels
{
    public class StringTableRow
    {
        public StringTableRow()
        {
            // I added this ctor and initialized the
            // StringValues property and the broken
            // custom binding to unbound columns started
            // to work.
            StringValues = new List<CultureNameAndStringValue>();
        }

        public long ResourceKeyId { get; set; }

        public string Key { get; set; }

        public long CategoryId { get; set; }

        public IList<CultureNameAndStringValue> StringValues { get; set; }
    }
}

这篇关于e.GetListSourceFieldValue在CustomUnboundColumnData事件处理程序中返回null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆