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 withTuve problemas trayéndome los valores del ModalDialog. No era capaz de encontrar los ID ni los Titles de los controles porque son creados dinámicamente. El truco que usé fue crear dos campos ocultos en el CreateChildControls:between and string scrp = @" "; 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>También me creé una clase de code behind
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; } }Lo que hago aquí es coger los parámetros del entorno en donde se ejecuta el web part y pasárselos al Silverlight. Uso el CurrentWeb para decirle a los web services del Silverlight cual es el contexto y el SelectedEntityID para resaltar la entidad que fue seleccionada la última vez que se abrió la ventana modal. Este es el código del Silverlight.
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