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

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

问题描述

我使用的是ASP.NET MVC 4项目中DevEx preSS控制。

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

我使用了 GridView控件扩展ASP.NET MVC未绑定列。在 CustomUnboundColumnData 事件处理程序中, e.GetListSourceFieldValue 总是为我返回null。

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.

我使用ASP.NET MVC 4 Visual Web Developer中前preSS 2010年版。我使用DevEx preSS扩展MVC v12.2.10.0。

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.

我的操作系统是Windows 7中,64位。不过,我现在用的扩展名是只有32位。

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

,因为它被分解成多个项目,其中大部分有大量的IP code,我为我的客户编写的,我不能出货了我的整个解决方案。但这里是我从code中的相关部分。

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视图引擎)
-------------------------------------------------- -----------------

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

@{
    ViewBag.Title = "Strings";
}

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

@Html.Partial("_StringsPartial", Model)

_StringsPartial.cshtml(的Razor视图引擎)
-------------------------------------------------- -----------------

@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;
        }
    }
}

视图模型
-------------------------------------------------- -----------------

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; }
    }
}

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

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));
        }
    }
}

模型视图模型转换:
-------------------------------------------------- -----------------

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;
        }
    }
}

的用户接口应该有点像上述中所示的画面。取决于由特定安装/部署/业务客户端支持培养物的数目由SQL查询返回的列数是可变的。因此,需要使用未绑定列。

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.

我拍下了这张照片不是通过这个code,但通过一个旧版本我的code,当我直接绑定数据到 System.Data.DataTable 并没有使用任何未绑定列。这一切都很好,直到我在的MVC /服务器端的操作编辑数据。所以,我从使用数据表到POCO和使用未绑定列所有文化切换。

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.

请帮助。

推荐答案

好吧,虽然我只有2个小时左右前张贴了这个问题,我现在已经有这样的烦恼超过8小时,一直在尝试各种办法来解决这一问题。

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.

如果您绑定您的DevEx preSS GridViewExtension 为ASP.NET MVC为定制POCO喜欢我的,POCO拥有一个或多个成员是集合任何一种,那么,你的必须的和的必须绝对的初始化那些重新present收藏在你的POCO的构造属性。

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.

有关例如,在我的情况下,模型是 StringTableRow 的,其中 StringTableRow 是一个列表POCO。

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

StringTableRow 类,我有一个命名属性 StringValues​​ 这是类型 IList的&LT; CultureNameAndStringValue&GT; ,这是一个集合。因此,对于我的code的工作,我在 StringTableRow 类的构造初始化 StringValues​​ 财产和一切都开始工作。

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天全站免登陆