DevExpress ASPxTreeList - 内联编辑

DevExpress ASPxTreeList - inline editing

我正在尝试在 ASP.NET 4.5 webforms 应用程序上使用 DevExpress ASPxTreeList 控件完成 内联编辑 - 类似这样(取自 DevExpress 演示站点) :

我想做的是两件事:

  1. 我希望能够将我的内联编辑限制在几列 - 例如只有 Budget 列应该是可编辑的。我希望 Budget 单元格变成文本框以允许数据输入 - 而所选行中的所有其他列应保持 原样 - 基本上作为标签(现在,当我启用内联编辑时,所有 单元格变成可编辑的控件 - 它们变成一个文本框,表明可以进行编辑)

  2. 我希望能够单击(或双击)该单元格以启用内联编辑 - 现在,我需要使用单独的命令按钮 "turn on"编辑。我该怎么做(如果有的话)?

  1. 如果你想要标签而不是可编辑控件,那么你可以简单地使用 EditCellTemplate 和里面的标签控件。

示例如下:

<dx:TreeListDataColumn FieldName="ContactName">
    <EditCellTemplate>
        <dx:ASPxLabel ID="ASPxLabel1" runat="server" Value='<%# Eval("ContactName") %>' />
    </EditCellTemplate>
</dx:TreeListDataColumn>
  1. ASPxTreeList 的此功能未由 DevExpress 实现。他们在支持中心提出了实施 «ASPxTreeList - Implement BatchEdit mode (like in ASPxGridView)». Here 的建议,您可以在 ASPxGridView.
  2. 中查看它的工作原理

因此,这是基于 this 示例的解决方法。
主要目标是将 DataCellTemplate 用于带有 ASPxTextBox 控件的列作为值编辑器。 ASPxTextBox 可以通过将特定样式应用于每个复合编辑器元素来完全自定义。这允许模拟所需的行为。您可以隐藏 ASPxTextBox 的边框和背景,仅在 ASPxTextBox 聚焦时显示边框。
这是示例:

<script>
    function GotFocus(s, e) {
        s.inputElement.style.cursor = "text";
    }
    function LostFocus(s, e) {
        s.inputElement.style.cursor = "default";
    }
</script>

<dx:ASPxTreeList ID="ASPxTreeList1" ClientInstanceName="tree" runat="server" Width="100%"
    DataSourceID="AccessDataSource1" AutoGenerateColumns="False" KeyFieldName="CategoryID"
    OnCustomCallback="ASPxTreeList1_CustomCallback">            
        <Columns>
            <dx:TreeListTextColumn FieldName="CategoryID" ReadOnly="True" VisibleIndex="0">
            </dx:TreeListTextColumn>
            <dx:TreeListTextColumn FieldName="CategoryName" VisibleIndex="1">
                <DataCellTemplate>
                    <dx:ASPxTextBox
                        ID="txtBox"
                        Width="100%"
                        runat="server"
                        Value='<%# Eval("CategoryName") %>'
                        Cursor="default"
                        BackColor="Transparent"
                        Border-BorderColor="Transparent"
                        FocusedStyle-Border-BorderColor="ActiveBorder"
                        ClientSideEvents-GotFocus="GotFocus"
                        ClientSideEvents-LostFocus="LostFocus" />
                </DataCellTemplate>
            </dx:TreeListTextColumn>
            <dx:TreeListTextColumn FieldName="Description" VisibleIndex="2">
                <DataCellTemplate>                    
                    <dx:ASPxTextBox 
                        ID="txtBox" 
                        Width="100%" 
                        runat="server" 
                        Value='<%# Eval("Description")%>' 
                        Cursor="default"
                        BackColor="Transparent"
                        Border-BorderColor="Transparent"                        
                        FocusedStyle-Border-BorderColor="ActiveBorder"
                        ClientSideEvents-GotFocus="GotFocus"
                        ClientSideEvents-LostFocus="LostFocus"/>
                </DataCellTemplate>                                   
            </dx:TreeListTextColumn>
        </Columns>            
        <Border BorderWidth="0px" />
    </dx:ASPxTreeList>
    <dx:ASPxButton ID="ASPxButton1" runat="server" AutoPostBack="False" Text="Post Modifications"
        Width="217px">
        <ClientSideEvents Click="
function(s, e) {
    tree.PerformCallback('post');
}" />
    </dx:ASPxButton>

<asp:AccessDataSource ID="AccessDataSource1" runat="server" DataFile="~/App_Data/nwind.mdb"
    SelectCommand="SELECT * FROM [Categories]" 
    UpdateCommand="UPDATE [Categories] SET [CategoryName] = ?, [Description] = ? WHERE [CategoryID] = ?">
    <UpdateParameters>
        <asp:Parameter Name="CategoryName" Type="String" />
        <asp:Parameter Name="Description" Type="String" />
        <asp:Parameter Name="CategoryID" Type="Int32" />
    </UpdateParameters>
</asp:AccessDataSource>
private List<Record> list = new List<Record>();

protected void Page_Load(object sender, EventArgs e)
{
    var column1 = ASPxTreeList1.DataColumns["CategoryName"];
    var column2 = ASPxTreeList1.DataColumns["Description"];

    var nodes = ASPxTreeList1.GetVisibleNodes();

    foreach (var node in nodes)
    {
        var txtBox1 = (ASPxTextBox)ASPxTreeList1.FindDataCellTemplateControl(node.Key, column1, "txtBox");
        var txtBox2 = (ASPxTextBox)ASPxTreeList1.FindDataCellTemplateControl(node.Key, column2, "txtBox");

        if (txtBox1 == null || txtBox2 == null)
            continue;

        int id = Convert.ToInt32(node.Key);
        list.Add(new Record(id, txtBox1.Text, txtBox2.Text));
    }
}

protected void ASPxTreeList1_CustomCallback(object sender, TreeListCustomCallbackEventArgs e)
{
    if (e.Argument == "post")
    {
        for (int i = 0; i < list.Count; i++)
        {
            AccessDataSource1.UpdateParameters["CategoryName"].DefaultValue = list[i].CategoryName;
            AccessDataSource1.UpdateParameters["Description"].DefaultValue = list[i].Description;
            AccessDataSource1.UpdateParameters["CategoryID"].DefaultValue = list[i].Id.ToString();
            //                AccessDataSource1.Update();  << Uncomment this line to update data!
        }

        ASPxTreeList1.DataBind();
    }
}