{
Primero empecemos guardando valor del Grupo seleccionado:
public partial class GruposAdmin : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
/// <summary>
/// Justo antes de que un grid de detalle consulte sus datos, guardamos en
/// Session el idGrupos de la fila maestra que se está expandiendo. Los
/// SqlDataSource de detalle lo leen con <asp:SessionParameter>.
/// Como el maestro sólo permite una fila expandida a la vez
/// (AllowOnlyOneMasterRowExpanded), el valor siempre corresponde al grupo
/// visible, incluso al insertar/editar/eliminar.
/// </summary>
protected void DetailGrid_BeforePerformDataSelect(object sender, EventArgs e)
{
ASPxGridView grid = (ASPxGridView)sender;
Session["idGrupos"] = grid.GetMasterRowKeyValue();
}
}
Ahora sigamos con la vista aspx
<div class="container">
<h2>Administrar Grupos</h2>
<p class="text-muted">Presione el signo <b>+</b> de un grupo para administrar sus Departamentos y Categorías.</p>
<%-- ================= GRID MAESTRO: GRUPOS ================= --%>
<dx:ASPxGridView ID="gvGrupos" runat="server" AutoGenerateColumns="False" DataSourceID="dsGrupos"
KeyFieldName="idGrupos" Theme="Aqua" Width="100%">
<Columns>
<dx:GridViewCommandColumn ShowEditButton="True" ShowDeleteButton="True" ShowNewButtonInHeader="True" VisibleIndex="0" Width="90px" />
<dx:GridViewDataTextColumn FieldName="codigo" Caption="Código" VisibleIndex="1" Width="120px" />
<dx:GridViewDataTextColumn FieldName="nombre" Caption="Nombre del grupo" VisibleIndex="2" />
<dx:GridViewDataCheckColumn FieldName="activo" Caption="Activo" VisibleIndex="3" Width="80px" />
</Columns>
<%-- Habilita la fila de detalle expandible con el botón "+" y sólo una abierta a la vez --%>
<SettingsDetail ShowDetailRow="True" AllowOnlyOneMasterRowExpanded="True" />
<Templates>
<DetailRow>
<div style="padding: 12px 20px;">
<div class="row">
<%-- ===== DETALLE 1: DEPARTAMENTOS DEL GRUPO (relación) ===== --%>
<div class="col-md-6">
<h4>Departamentos del grupo</h4>
<dx:ASPxGridView ID="gvDepartamentos" runat="server" AutoGenerateColumns="False"
DataSourceID="dsGruposDepartamentos" KeyFieldName="idGruposDepartamentos" Theme="Aqua" Width="100%"
OnBeforePerformDataSelect="DetailGrid_BeforePerformDataSelect">
<Columns>
<dx:GridViewCommandColumn ShowEditButton="True" ShowDeleteButton="True" ShowNewButtonInHeader="True" VisibleIndex="0" Width="90px" />
<%-- Se elige el departamento existente desde un combo --%>
<dx:GridViewDataComboBoxColumn FieldName="idDepartamentos" Caption="Departamento" VisibleIndex="1">
<PropertiesComboBox DataSourceID="dsDepartamentosLookup"
TextField="nombre" ValueField="idDepartamentos" ValueType="System.Int32"
DropDownStyle="DropDownList" IncrementalFilteringMode="Contains" />
</dx:GridViewDataComboBoxColumn>
<dx:GridViewDataTextColumn FieldName="desciprion" Caption="Descripción" ReadOnly="True" VisibleIndex="2" />
<dx:GridViewDataCheckColumn FieldName="activo" Caption="Activo" ReadOnly="True" VisibleIndex="3" Width="70px" />
</Columns>
<SettingsText EmptyDataRow="Este grupo no tiene departamentos." />
</dx:ASPxGridView>
<%-- Relación grupo <-> departamento (lo que se crea/edita/borra) --%>
<asp:SqlDataSource ID="dsGruposDepartamentos" runat="server"
ConnectionString="<%$ ConnectionStrings:SPOSDBConnectionString %>"
SelectCommand="SELECT gd.[idGruposDepartamentos], gd.[idDepartamentos], d.[desciprion], d.[activo]
FROM [GruposDepartamentos] gd
INNER JOIN [Departamentos] d ON d.[idDepartamentos] = gd.[idDepartamentos]
WHERE gd.[idGrupos] = @idGrupos"
InsertCommand="INSERT INTO [GruposDepartamentos] ([idGrupos], [idDepartamentos]) VALUES (@idGrupos, @idDepartamentos)"
UpdateCommand="UPDATE [GruposDepartamentos] SET [idDepartamentos] = @idDepartamentos WHERE [idGruposDepartamentos] = @idGruposDepartamentos"
DeleteCommand="DELETE FROM [GruposDepartamentos] WHERE [idGruposDepartamentos] = @idGruposDepartamentos">
<SelectParameters>
<asp:SessionParameter Name="idGrupos" SessionField="idGrupos" Type="Int32" />
</SelectParameters>
<InsertParameters>
<asp:SessionParameter Name="idGrupos" SessionField="idGrupos" Type="Int32" />
<asp:Parameter Name="idDepartamentos" Type="Int32" />
</InsertParameters>
<UpdateParameters>
<asp:Parameter Name="idDepartamentos" Type="Int32" />
<asp:Parameter Name="idGruposDepartamentos" Type="Int32" />
</UpdateParameters>
<DeleteParameters>
<asp:Parameter Name="idGruposDepartamentos" Type="Int32" />
</DeleteParameters>
</asp:SqlDataSource>
<%-- Catálogo para el combo de departamentos --%>
<asp:SqlDataSource ID="dsDepartamentosLookup" runat="server"
ConnectionString="<%$ ConnectionStrings:SPOSDBConnectionString %>"
SelectCommand="SELECT [idDepartamentos], [nombre] FROM [Departamentos] ORDER BY [nombre]">
</asp:SqlDataSource>
</div>
<%-- ===== DETALLE 2: CATEGORÍAS DEL GRUPO (relación) ===== --%>
<div class="col-md-6">
<h4>Categorías del grupo</h4>
<dx:ASPxGridView ID="gvCategorias" runat="server" AutoGenerateColumns="False"
DataSourceID="dsGruposCategorias" KeyFieldName="idGruposCategorias" Theme="Aqua" Width="100%"
OnBeforePerformDataSelect="DetailGrid_BeforePerformDataSelect">
<Columns>
<dx:GridViewCommandColumn ShowEditButton="True" ShowDeleteButton="True" ShowNewButtonInHeader="True" VisibleIndex="0" Width="90px" />
<%-- Se elige la categoría existente desde un combo --%>
<dx:GridViewDataComboBoxColumn FieldName="idCategorias" Caption="Categoría" VisibleIndex="1">
<PropertiesComboBox DataSourceID="dsCategoriasLookup"
TextField="nombre" ValueField="idCategorias" ValueType="System.Int32"
DropDownStyle="DropDownList" IncrementalFilteringMode="Contains" />
</dx:GridViewDataComboBoxColumn>
<dx:GridViewDataTextColumn FieldName="descripcion" Caption="Descripción" ReadOnly="True" VisibleIndex="2" />
<dx:GridViewDataTextColumn FieldName="codigo" Caption="Código" ReadOnly="True" VisibleIndex="3" Width="100px" />
</Columns>
<SettingsText EmptyDataRow="Este grupo no tiene categorías." />
</dx:ASPxGridView>
<%-- Relación grupo <-> categoría (lo que se crea/edita/borra) --%>
<asp:SqlDataSource ID="dsGruposCategorias" runat="server"
ConnectionString="<%$ ConnectionStrings:SPOSDBConnectionString %>"
SelectCommand="SELECT gc.[idGruposCategorias], gc.[idCategorias], c.[descripcion], c.[codigo]
FROM [GruposCategorias] gc
INNER JOIN [Categorias] c ON c.[idCategorias] = gc.[idCategorias]
WHERE gc.[idGrupos] = @idGrupos"
InsertCommand="INSERT INTO [GruposCategorias] ([idGrupos], [idCategorias]) VALUES (@idGrupos, @idCategorias)"
UpdateCommand="UPDATE [GruposCategorias] SET [idCategorias] = @idCategorias WHERE [idGruposCategorias] = @idGruposCategorias"
DeleteCommand="DELETE FROM [GruposCategorias] WHERE [idGruposCategorias] = @idGruposCategorias">
<SelectParameters>
<asp:SessionParameter Name="idGrupos" SessionField="idGrupos" Type="Int32" />
</SelectParameters>
<InsertParameters>
<asp:SessionParameter Name="idGrupos" SessionField="idGrupos" Type="Int32" />
<asp:Parameter Name="idCategorias" Type="Int32" />
</InsertParameters>
<UpdateParameters>
<asp:Parameter Name="idCategorias" Type="Int32" />
<asp:Parameter Name="idGruposCategorias" Type="Int32" />
</UpdateParameters>
<DeleteParameters>
<asp:Parameter Name="idGruposCategorias" Type="Int32" />
</DeleteParameters>
</asp:SqlDataSource>
<%-- Catálogo para el combo de categorías --%>
<asp:SqlDataSource ID="dsCategoriasLookup" runat="server"
ConnectionString="<%$ ConnectionStrings:SPOSDBConnectionString %>"
SelectCommand="SELECT [idCategorias], [nombre] FROM [Categorias] ORDER BY [nombre]">
</asp:SqlDataSource>
</div>
</div>
</div>
</DetailRow>
</Templates>
</dx:ASPxGridView>
<%-- ================= ORIGEN DE DATOS DEL MAESTRO ================= --%>
<asp:SqlDataSource ID="dsGrupos" runat="server"
ConnectionString="<%$ ConnectionStrings:SPOSDBConnectionString %>"
SelectCommand="SELECT [idGrupos], [codigo], [nombre], [activo] FROM [Grupos]"
InsertCommand="INSERT INTO [Grupos] ([codigo], [nombre], [activo]) VALUES (@codigo, @nombre, @activo)"
UpdateCommand="UPDATE [Grupos] SET [codigo] = @codigo, [nombre] = @nombre, [activo] = @activo WHERE [idGrupos] = @idGrupos"
DeleteCommand="DELETE FROM [Grupos] WHERE [idGrupos] = @idGrupos">
<InsertParameters>
<asp:Parameter Name="codigo" Type="String" />
<asp:Parameter Name="nombre" Type="String" />
<asp:Parameter Name="activo" Type="Boolean" />
</InsertParameters>
<UpdateParameters>
<asp:Parameter Name="codigo" Type="String" />
<asp:Parameter Name="nombre" Type="String" />
<asp:Parameter Name="activo" Type="Boolean" />
<asp:Parameter Name="idGrupos" Type="Int32" />
</UpdateParameters>
<DeleteParameters>
<asp:Parameter Name="idGrupos" Type="Int32" />
</DeleteParameters>
</asp:SqlDataSource>
</div>
}