Hello,

I'm trying to develop a litle framework based on ext.net.

<ul>[*]I've a MasterPage that is inherited for registers. Each subject has its inheritance.[*]Inside this MasterPage there is a UserControl used for Search wich its
grid columns and filter fields are built dynamically;[/list]
<body>
    <form id="form1" runat="server">
        <ext:ResourceManager ID="ResourceManager1" runat="server"  ScriptMode="Release"/>
        <ext:Panel ID="ToolbarsPanel" runat="server" Border="false" BodyStyle="padding:10px;" Layout="Fit">
            <TopBar>
                <ext:Toolbar ID="TopBar" runat="server">
                    <Items>
                        <ext:Button ID="btnFind" runat="server" Text="Pesquisar" Icon="Find">
                            <DirectEvents>
                                <Click OnEvent="btnFind_Click">
                                    <EventMask ShowMask="true" Msg="Aguarde..." />
                                </Click>
                            </DirectEvents>
                        </ext:Button>
                        <ext:Button ID="btnSave" runat="server" Text="Salvar" Icon="Disk">
                            <DirectEvents>
                                <Click OnEvent="btnSave_Click" ViewStateMode="Enabled">
                                    <EventMask ShowMask="true" Msg="Aguarde..." />
                                </Click>
                            </DirectEvents>
                        </ext:Button>
                    </Items>
                </ext:Toolbar>
            </TopBar>
            <Content>
                <asp:ContentPlaceHolder ID="cph" runat="server">
                 </asp:ContentPlaceHolder>
            </Content>
        </ext:Panel>
        <ucl:Search ID="ucSearch" runat="server"/>
    </form>
</body>
CodeBehind
    [DirectMethodProxyID(IDMode = DirectMethodProxyIDMode.None)]
    public partial class MasterCadastro : System.Web.UI.MasterPage
    {
        public event DirectEvent.DirectEventHandler Search;
        public event DirectEvent.DirectEventHandler Save;

        protected void btnFind_Click(object sender, DirectEventArgs e)
        {
            Search(sender, e);
        }

        protected void btnSave_Click(object sender, DirectEventArgs e)
        {
            Save(sender, e);
        }

        public UCSearchUserControl SearchControl
        {
            get
            {
                return this.ucSearch;
            }
        }
   }
UCSearch UserControl:
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="UCSearchUserControl.ascx.cs" Inherits="Shared.Search.UCSearchUserControl" %>
<%@ Register assembly="Ext.Net" namespace="Ext.Net" tagprefix="ext" %>

<ext:Window 
    ID="winSearch" 
    runat="server" 
    Icon="Find" 
    Title="Pesquisar" 
    Resizable="false"
    Hidden="true"
    AutoShow="false"
    Plain="true"
    Modal="true" 
    Width="700" 
    Height="500">
    <Items>
        <ext:BorderLayout runat="server">
            <North>
                <ext:Panel ID="pnlBody" runat="server" LabelAlign="Top" Layout="Form" Border="false" Padding="5" AutoHeight="true">
                </ext:Panel>
            </North>
            <Center>
                <ext:GridPanel ID="gridPanel" runat="server" 
                     Border="false" 
                     TrackMouseOver="true">
                     <Store>
                        <ext:Store ID="searchStore" runat="server" IgnoreExtraFields="false">
                            <Reader>
                                <ext:JsonReader>
                                </ext:JsonReader>
                            </Reader>
                        </ext:Store>
                     </Store>
                     <SelectionModel>
                        <ext:RowSelectionModel runat="server"/>
                     </SelectionModel>
                     <ColumnModel ID="cmGridPanel" runat="server">
                        <Columns>
                        </Columns>
                     </ColumnModel>
                     <DirectEvents>
                        <RowDblClick OnEvent="OnRowDblClick" ViewStateMode="Enabled">
                            <ExtraParams>
                                <ext:Parameter Name="data" Mode="Raw" Encode="true" Value="this.selModel.selections.items[0].data" />
                            </ExtraParams>
                        </RowDblClick>
                     </DirectEvents>
                     <BottomBar>
                        <ext:PagingToolbar ID="pagingTool" runat="server" PageSize="13" HideRefresh="true" AutoShow="true"/>
                     </BottomBar>
                </ext:GridPanel>
            </Center>
        </ext:BorderLayout>
    </Items>
    <Buttons>
        <ext:Button runat="server" ID="btnPesquisar" Text="Pesquisar" Icon="Find" OnDirectClick="btnPesquisa_Click">
            <DirectEvents>
                <Click OnEvent="btnPesquisa_Click">
                    <EventMask CustomTarget="#{gridPanel}" ShowMask="true" />
                </Click>
            </DirectEvents>
        </ext:Button>
        <ext:Button runat="server" ID="btnSelecionar" Text="Selecionar" Icon="Accept">
            <DirectEvents>
                <Click OnEvent="OnRowDblClick" ViewStateMode="Enabled">
                    <ExtraParams>
                        <ext:Parameter Name="data" Mode="Raw" Encode="true" Value="#{gridPanel}.selModel.selections.items[0].data" />
                    </ExtraParams>
                </Click>
            </DirectEvents>
        </ext:Button>  
    </Buttons>
</ext:Window>
UCSearch CodeBehind:
    public partial class UCSearchUserControl : UserControl
    {
        public event ReturnSearchEventHandler ReturnSearch;

        protected void Page_Load(object sender, EventArgs e)
        {
        }

        public void Show(Control animateTarget)
        {
            winSearch.Show(animateTarget);
        }

        protected void OnRowDblClick(object sender, DirectEventArgs e)
        {
            SearchParams searchParams = SearchBase.GetSearch(this.Context);  // From Session
            ReturnSearchEventArgs args = new ReturnSearchEventArgs();
            args.Data = JSON.Deserialize(e.ExtraParams["data"], searchParams.ReturnSearchType);
            args.CallerID = searchParams.CallerID;

            winSearch.Hide();
            SearchBase.RemoveSearch(this.Context);  // From Session

            ReturnSearch(sender, args);
        }


        public SearchParams Config
        {
            set
            {
                searchStore.RemoveFields();

                winSearch.Title = value.Title;
                               
                PropertyInfo[] returnPropInfo;
                returnPropInfo = value.ReturnSearchType.GetProperties(BindingFlags.Instance | BindingFlags.Public);

                for (int i = 0; i < returnPropInfo.Length; i++)
                {
                    searchStore.AddField(new RecordField(returnPropInfo[i].Name));
                }
                
                // Add form fields 
                pnlBody.RemoveAll();
                foreach (SearchParam param in value.Params)
                {
                    if (param.SearchComponent != null)
                    {
                        param.SearchComponent.ID = string.Format("{0}_{1}", pnlBody.ClientID, param.SearchComponent.ID);
                        param.SearchComponent.AddTo(pnlBody);
                    }
                }

                pnlBody.UpdateContent();
                ColumnModel cm = gridPanel.ColumnModel;

                // add grid columns
                cm.Columns.Clear();
                cm.Columns.AddRange(value.Columns);

                pagingTool.SetPageIndex(1);

                gridPanel.Reconfigure();

                SearchBase.SetSearch(this.Context, value);  // Into Session
            }
        }

        public void btnPesquisa_Click(object sender, DirectEventArgs e)
        {
            SearchParams searchParams = SearchBase.GetSearch(this.Context);  // From Session

            DataAccessManager dam = DataAccessManager.GetDefaultDataAccessManager(this.Context);
            IDataAccess da = dam.CreateDataAccessObject();

            try
            {
                List<DataAccessParameter> parameters = new List<DataAccessParameter>();

                foreach (SearchParam param in searchParams.Params)
                {
                    object valor = null;

                    if (param.HiddenValue != null)
                    {
                        valor = param.HiddenValue;
                    }
                    else
                    {
                        if (this.Request[param.SearchComponent.ID + "_value"] != null)
                        {
                            valor = this.Request[param.SearchComponent.ID + "_value"];
                        }
                        else
                        {
                            valor = this.Request[param.SearchComponent.ID];
                        }
                    }

                    parameters.Add(new DataAccessParameter(param.ParamName, param.DBType,
                           Util.DataConvert.ToDatabase(valor)));
                }

                da.OpenConnection();

                DataTable dataTable = new DataTable();
                da.FillDataTable(searchParams.CommandText, searchParams.CommandType, parameters, dataTable);

                pagingTool.SetPageIndex(1);

                gridPanel.Store.Primary.DataSource = dataTable;
                gridPanel.Store.Primary.DataBind();

            }
            finally
            {
                if (da != null)
                {
                    da.CloseConnection();
                    da.Dispose();
                }
            }
        }
    }
Parameter for create searchs
    public class SearchParams
    {
        public SearchParams()
        {
            Params = new List<SearchParam>();
            Columns = new ColumnCollection();
        }

        public MethodInfo ReturnSearchInfo { get; set; }
        public String CallerID { get; set; }
        public Type ReturnSearchType;
        public Int16 BodyHeight { get; set; }
        public String Title { get; set; }
        public String CommandText { get; set; }
        public CommandType CommandType { get; set; }
        public List<SearchParam> Params { get; set; }

        public ColumnCollection Columns { get; set; }
    }

    public class SearchParam
    {
        public SearchParam()
        {

        }

        private object hiddenValue;
        public object HiddenValue 
        {
            get { return hiddenValue; }
            set
            {
                if (searchComponent != null)
                {
                    throw new Exception("It is not possible set 'HiddenValue' and 'SearchComponent' at the same parameter!");
                }
                hiddenValue = value;
            }
        }

        private Field searchComponent;
        public Field SearchComponent 
        {
            get { return searchComponent; }
            set
            {
                if (searchComponent != null)
                {
                    throw new Exception("It is not possible set 'HiddenValue' and 'SearchComponent' at the same 
parameter!");
                }
                searchComponent = value;
            }
        }
        public String ParamName { get; set; }
        public DbType DBType { get; set ; }
    }

Here is the final user interface:
<asp:Content ID="Content2" ContentPlaceHolderID="cph" runat="server">

    <ext:Store runat="server" IgnoreExtraFields="false" ID="storePrinciple" EnableViewState="true">
        <Reader>
            <ext:JsonReader IDProperty="idPrinciple">
                <Fields>
                    <ext:RecordField Name="idPrinciple" Type="Int"/>
                    <ext:RecordField Name="dsPrinciple" />
                </Fields>
            </ext:JsonReader>
        </Reader>
    </ext:Store>

    <ext:Panel ID="pnlForm" runat="server" LabelAlign="Top" Layout="Form" Border="false">
        <Items>
            <ext:NumberField ID="nrIdConcept" runat="server" FieldLabel="ID" Width="80" MaxLength="6" Disabled="true"/>     
            <ext:TextField ID="txtNmConcept" runat="server" FieldLabel="Name" Width="270"/> 
            
            
            <ext:GridPanel   ID="gdrPrinciple" runat="server"  Frame="true" StoreID="storePrinciple"
                Title="Principle" AutoHeight="true" Width="560">
                <ColumnModel ID="clmnMdlPrinciple" runat="server">
                    <Columns>
                        <ext:Column ColumnID="clIdPrinciple"  DataIndex="idPrinciple" Header="ID" Width="80"  Align="Center"/>
                        <ext:Column DataIndex="dsPrinciple" Header="Name" Width="370" />
                    </Columns>
                </ColumnModel>
                <SelectionModel>
                    <ext:RowSelectionModel runat="server" SingleSelect="true"/>
                </SelectionModel>
                <Plugins>
                    <ext:GridPanelMaintainScrollPositionOnRefresh runat="server" />
                </Plugins>
                <BottomBar>
                    <ext:Toolbar ID="Toolbar1" runat="server">
                        <Items>
                            <ext:Button ID="btnInsertPrinciple" Text="Adicionar" Icon="Add" runat="server">
                                <DirectEvents>
                                    <Click OnEvent="btnInsertPrinciple_Click">
                                        <EventMask ShowMask="true" CustomTarget="#{gdrPrinciple}" />
                                    </Click>
                                </DirectEvents>
                            </ext:Button>
                        </Items>
                    </ext:Toolbar>
                </BottomBar>
            </ext:GridPanel>
        </Items>
    </ext:Panel>
</asp:Content>
         protected void Page_Load(object sender, EventArgs e)
        {
            master = (MasterCadastro)Master;

            master.Search += new ComponentDirectEvent.DirectEventHandler(OnSearch);
            master.Save += new ComponentDirectEvent.DirectEventHandler(OnSave);
            master.SearchControl.ReturnSearch += new ReturnSearchEventHandler(OnReturnSearch);
        }

        public void OnReturnSearch(Object sender, ReturnSearchEventArgs e)
        {
            if (e.CallerID == master.ID)
            {
                BVConcept retornoPesquisa = (BVConcept)e.Data;
                nrIdConcept.Text = retornoPesquisa.id_concept.ToString();
                txtNmConcept.Text = retornoPesquisa.ds_concept.ToString();
            }
            else if (e.CallerID == btnInsertPrinciple.ID)
            {
               
                BVPrinciple retornoPesquisa = (BVPrinciple )e.Data;
                
                /*
                     BEFORE I INSERT THE RECORD ON STORE I NEED TO VALIDATE IT IS ALREADY INSERTED.
                     HOW CAN I GET THE STORE DATA HERE TO VALIDADE DUPLICATED IDS INTO THE STORE?
                */

                storePrinciple.AddRecord(retornoPesquisa);

            }
        }

        public void btnInsertPrinciple_Click(object sender, DirectEventArgs e)
        {
            SearchPrinciple.Search(Context, master.SearchControl, sender, btnInsertPrinciple.ID);
        }
       
        public void OnSearch(object sender, DirectEventArgs e)
        {
           SearchConcept.Search(Context, master.SearchControl, sender, master.ID);
        }

        public void OnSave(object sender, Ext.Net.DirectEventArgs e)
        {
            BVConcept valueConcept;  // Master / Detail
            try
            {
                valueConcept= new BVConcept ();
                valueConcept.idVacinaMedicamento = Util.DataConvert.ToInt(nrIdConcept.Text);
                valueConcept.nmVacinaMedicamento = txtNmConcept.Text;
               
                /*
                valueConcept.Principles  List<BVPrinciple>

                HOW CAN I GET PRINCIPLE'S STORE HERE?  THIS EVENT IS THROWNBY A MASTER PAGE.

               */

               ControllerConcept.Save(valueConcept);     

            }
            finally
            {
                valueConcept= null;
            }
        }