Lo que queríamos conseguir era filtrar elementos en un List View Web Part por Entidad. En nuestra solución tenemos una jerarquía de entidades por lo que pensamos que sería buena idea que el web part mostrase la jerarquía como un árbol.
Bien, así que necesitamos un web part con un TreeView que sea capaz de mandar la entidad seleccionada como filtro a un LVWP. Fantástico. Lo hice... Y no le gustó a nadie. Lo querían en Silverlight y no solo eso, lo querían en una ventana pop up. Sip, me cogieron, nunca había hecho nada parecido pero, ¿Quién dijo miedo?
Es un montón de código, la mayor parte feo así que solo postearé la parte interesante (básicamente la parte relacionada con la comunicación entre las páginas y el Silverlight) y las URLs de donde cogí las ideas.
Lo primero es poner a funcionar un Filter Provider Web Part. Para ello seguí las instrucciones de aquí. Primero lo intenté con un IWebPartRow, pero no era lo que yo quería así que cambié a ITransformableFilterValues. Esta parte es bastante simple así que no comentaré nada más.
La segunda parte es crear una ventana emergente. Después de googlear
- protected override void OnLoad(EventArgs e)
- {
- if (Page.IsPostBack)
- {
- if (!string.IsNullOrEmpty(GetFormValue("HiddenEntityName")))
- {
- Page.Session["SelectedEntityName"] = Page.Request.Form["HiddenEntityName"];
- Page.Session["SelectedEntityID"] = Page.Request.Form["HiddenEntityID"];
- RenderHeader();
- //SelectedEntityText.Text = string.Format("{0} ", Page.Request.Form["HiddenEntityName"], Page.Request.Form["HiddenEntityID"]);
- }
- else
- RenderHeader();
- }
- string CurrentWeb = SPContext.Current.Web.Url;
- string height = "500";
- string width = "500";
- string page = "/_layouts/stratex/EntityTree.aspx";
- // use next line for direct with <base target="_self"> between and
- string scrp = @"
- <script javascript??="" text="" type="">
- var ReturnValue = new Array("","");
- function ShowModalDialog(){
- ReturnValue = window.showModalDialog('" + page + "?CurrentWeb=" + CurrentWeb + "&SelectedEntityID=" + Page.Session["SelectedEntityID"] + "&dialogHeight:" + height + " px;dialogWidth:" + width + @" px;');
- if(ReturnValue[0] != null){
- document.getElementById('HiddenEntityName').value = ReturnValue[0];
- document.getElementById('HiddenEntityID').value = ReturnValue[1];
- __doPostBack('','');
- }
- }
- </script>";
- Type t = this.GetType();
- if (!Page.ClientScript.IsClientScriptBlockRegistered(t, "bindWebserviceToAutocomplete"))
- Page.ClientScript.RegisterClientScriptBlock(t, "bindWebserviceToAutocomplete", scrp);
- }
- protected override void CreateChildControls()
- {
- base.CreateChildControls();
- ...
- Page.ClientScript.RegisterHiddenField("HiddenEntityName", "");
- Page.ClientScript.RegisterHiddenField("HiddenEntityID", "");
- ...
- }
La próxima parte es crear la página aspx para el modal dialog. La guardé en un directorio que me creé en _layouts. El código de la página quedó así:
- <%@ Page Language="C#" Inherits="StratExFramework.EntityTree,StratExFramework,Version=2.2.0.0,Culture=neutral,PublicKeyToken=311246df7412ca98" %>
- <html>
- <head>
- <title>Select Entity for filtering</title>
- <script type='text/javascript'>
- function PassParameterAndClose(EntityName, EntityID) {
- window.returnValue = new Array( EntityName, EntityID) ;
- var version = parseFloat(navigator.appVersion.split('MSIE')[1]);
- if (version >= 7)
- { window.open('', '_parent', ''); }
- else
- { window.opener = self; }
- window.close();
- }
- </script>
- </head>
- <body></body>
- </html>
- public class EntityTree : WebPartPage
- {
- string CurrentWeb;
- string SelectedEntityID;
- protected void Page_Load(object sender, System.EventArgs e)
- {
- CurrentWeb = Request.Params["CurrentWeb"];
- SelectedEntityID = Request.Params["SelectedEntityID"];
- }
- protected override void CreateChildControls()
- {
- base.CreateChildControls();
- string Source = CurrentWeb + "/Lists/XAPLibrary/SilverlightEntityTreeSelector.xap";
- string SilverlightHeight = "515";
- string SilverlightWidth = "500";
- LiteralControl obj = new LiteralControl();
- obj.Text = "<object id='silverlightHost' style='height: " + SilverlightHeight + "; width: " + SilverlightWidth + @"; margin: 0; padding: 0;' data='data:application/x-silverlight-2,' type='application/x-silverlight-2'>
- <param name='Source' value='" + Source + @"' />
- <param name='MinRuntimeVersion' value='3.0.40624.0' />
- <param name='Background' value='#FFFFFFFF' />
- <param name='initParams' value='" +
- string.Format("{0}={1}", "site", HttpUtility.UrlEncode(CurrentWeb)) +
- string.Format(", {0}={1}", "selectedentityid", HttpUtility.UrlEncode(SelectedEntityID)) +
- @"' />
- </object>";
- this.Controls.Add(obj);
- }
- public override void VerifyRenderingInServerForm(Control control)
- {
- return;
- }
- }
- namespace SilverlightEntityTreeSelector
- {
- public partial class MainPage : UserControl
- {
- public MainPage()
- {
- InitializeComponent();
- Tree.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(Tree_PropertyChanged);
- Tree.Show(string.Empty);
- }
- void Tree_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
- {
- if (e.PropertyName == "SelectedEntityID")
- HtmlPage.Window.Invoke("PassParameterAndClose", Tree.SelectedEntityName, Tree.SelectedEntityID);
- else if (e.PropertyName == "TreeLoaded")
- if (Application.Current.Resources.Contains("selectedentityid"))
- if (!string.IsNullOrEmpty(Application.Current.Resources["selectedentityid"] as string))
- Tree.ChangeSelectedItemTo(Application.Current.Resources["selectedentityid"] as string);
- }
- }
- }
Ya tenemos todos los componentes.
Esto funciona de la siguiente manera: Seleccionas una entidad en el árbol de Silverlight, luego el Silverlight llama a la función javascript de la ventana modal y que pasa los parámetros al web part padre y cierra el popup. Finalmente el web part manda el filtro al List View WebPar.
Si usas este código te faltarán algunos métodos, pero lo que quería compartir aquí es el método que he seguido para conseguirlo
No hay comentarios:
Publicar un comentario