2015-02-11 22 views
0

我正在尝试关注the DevExpress documentation example on cloning rows。基础很容易得到正确,但是当您尝试克隆值类型以外的属性时,事情会变得棘手。使用CustomButtonCallback克隆引用类型属性

首次尝试/建立一个摄制:

我已经收窄我的真实场景的问题的一小(ISH)摄制。以下是全新创建的ASP.NET 2.0 webforms应用程序的全部内容。首先,假设这些域对象(即会兼作DTO太在这里):

public class Qualification 
{ 
    public long Id { get; set; } 
    public string Title { get; set; } 
} 

public class Person 
{ 
    public long Id { get; set; } 
    public string Name { get; set; } 
    public Qualification Qualification { get; set; } 
} 

然而,像两个快速“N脏数据源类,所以:

public class QualificationOds 
{ 
    public static List<Qualification> Qualificiations = new List<Qualification> 
    { 
     new Qualification { Id = 1, Title = "Doctore" } 
    }; 

    public List<Qualification> GetRecords() 
    { 
     return Qualificiations; 
    } 
} 

public class PeopleOds 
{ 
    public List<Person> GetRecords() 
    { 
     return new List<Person> 
     { 
      new Person 
      { 
       Id = 1, 
       Name = "John Doe", 
       Qualification = QualificationOds.Qualificiations[0] 
      } 
     }; 
    } 
} 

Default.aspx页首先注册dx到DevExpress的命名空间:

<%@ Register Assembly="DevExpress.Web.ASPxGridView.v11.1, Version=11.1.11.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" Namespace="DevExpress.Web.ASPxGridView" TagPrefix="dx" %> 
<%@ Register Assembly="DevExpress.Web.ASPxEditors.v11.1, Version=11.1.11.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" Namespace="DevExpress.Web.ASPxEditors" TagPrefix="dx" %> 

,并与该代码中有一个单一的形式:

<asp:ObjectDataSource runat="server" ID="peopleDataSource" TypeName="DevxTest.PeopleOds" SelectMethod="GetRecords" /> 
<asp:ObjectDataSource runat="server" ID="qualificationsDataSource" TypeName="DevxTest.QualificationOds" SelectMethod="GetRecords" /> 

<dx:ASPxGridView 
    runat="server" 
    id="grvPeople" 
    KeyFieldName="Id" 
    DataSourceID="peopleDataSource" 
    OnCustomButtonCallback="grid_CustomButtonCallback" 
    OnInitNewRow="grid_InitNewRow"> 
    <Columns> 
     <dx:GridViewCommandColumn> 
      <EditButton Visible="true" /> 
      <CustomButtons> 
       <dx:GridViewCommandColumnCustomButton ID="Clone" Text="Clone" /> 
      </CustomButtons> 
     </dx:GridViewCommandColumn> 
     <dx:GridViewDataTextColumn FieldName="Name" /> 
     <dx:GridViewDataComboBoxColumn FieldName="Qualification.Id" > 
      <PropertiesComboBox 
       DataSourceID="qualificationsDataSource" 
       TextField="Title" 
       ValueField="Id" 
       ValueType="System.Int64" /> 
     </dx:GridViewDataComboBoxColumn> 
    </Columns> 
</dx:ASPxGridView> 

后面的代码包含的代码克隆一行到一个新的编辑形式,基于上述DevExpress的例子,像这样:

private string[] fieldsToCopy = { "Name", "Id" }; 
private Hashtable valuesToClone; 

protected void grid_CustomButtonCallback(object sender, ASPxGridViewCustomButtonCallbackEventArgs e) 
{ 
    if (e.ButtonID != "Clone") return; 

    valuesToClone = new Hashtable(); 

    foreach (var fieldName in fieldsToCopy) 
    { 
     valuesToClone[fieldName] = grvPeople.GetRowValues(e.VisibleIndex, fieldName); 
    } 

    grvPeople.AddNewRow(); 
} 

protected void grid_InitNewRow(object sender, DevExpress.Web.Data.ASPxDataInitNewRowEventArgs e) 
{ 
    if (valuesToClone == null) return; 

    foreach (string fieldName in fieldsToCopy) 
    { 
     e.NewValues[fieldName] = valuesToClone[fieldName]; 
    } 
} 

此作品为Name财产,但没有这么多的Qualification财产。它显示了这样的网页上:

edit form with empty dropdown for Qualification

我也试过"Qualification.Id""Qualification"字段名复制,但没有骰子。无论如何,我很确定它应该是"Id",正如我的示例中那样,因为调试器仅在该情况下显示正确的GetRowValues返回值。

第二次尝试/自定义代码来处理下拉:

所以我想我需要有一些自定义代码来设置的NewValue的下拉菜单。首先,我对资格列上创建EditItemTemplate像这样:

<EditItemTemplate> 
    <dx:ASPxComboBox 
     runat="server" 
     ID="qualificationCombo" 
     DataSourceID="qualificationsDataSource" 
     TextField="Title" 
     ValueField="Id" 
     ValueType="System.Int64" /> 
</EditItemTemplate> 

然后我这个代码添加到grid_InitNewRow

// Attempt to set the combo box to a value: 
var column = grvPeople.Columns["Qualification"] as GridViewDataColumn; 
var comboBox = grvPeople.FindEditRowCellTemplateControl(column, "qualificationCombo") as ASPxComboBox; 
var item = comboBox.Items.FindByValue(valuesToClone["Id"]); 
item.Selected = true; 

和它的作品!但是,现在Name不再被克隆。它看起来像这样:

DevExpress grid after hitting "Clone" with empty Name field

我不知道为什么,但添加的代码具有副作用造成NewValues二传手方法失败。

底线:

底线很简单:我怎么改变DevExpress的例子为一个也可以复制引用类型的属性?


PS。我也cross-posted my question on the DevExpress support forum

+0

网格中有两列:“名称”和“Qualification.Id”。在grid_CustomButtonCallback函数中复制值时,需要将以下值作为第二个参数传递给ASPxGridView.GetRowValues方法:“Name”和“Id”。我想第二个值应该是“Qualification.Id”,而不是“Id”。 – Uranus 2015-02-12 03:52:56

+0

感谢@Uranus,您的评论很有用。我已经尝试过了,但是用'EditItemTemplate'完成了,那么它仍然不起作用。 DevExpress支持基本上回答相同。我还找到了需要EditItemTemplate时的解决方案/解决方法,因此我将所有内容编译为下面的答案。 – Jeroen 2015-02-12 10:29:19

回答

0

您提到"Qualification.Id"不起作用,但您很可能试过,而EditItemTemplate在那里。如果没有这样的模板,那么该代码实际上起作用。

是完整的,改变fieldsToCopy行代码:

private string[] fieldsToCopy = { "Name", "Qualification.Id" }; 

而且确保没有EditItemTemplate,那么它会工作。

或者,如果您由于某种原因被阻止在EditItemTemplate,那么有一个“解决方案”可以确保该模板中的ComboBox被绑定到克隆值。请确保您挂接到OnDataBound的组合框用下面的代码:

protected void qualificationCombo_DataBound(object sender, EventArgs e) 
{ 
    var column = grvPeople.Columns["Qualification"] as GridViewDataColumn; 
    var comboBox = grvPeople.FindEditRowCellTemplateControl(column, "qualificationCombo") as ASPxComboBox; 
    var item = comboBox.Items.FindByValue(valuesToClone["Id"]); 
    item.Selected = true; 
} 

这将组合框设置适当,以克隆的价值,同时也留下了纯场不变的e.NewValues方法。