Calling JS class methods from Silverlight application

I’m working on a project in which we have to call some JS method of the containing page from a Silverlight application.

It seems to be really straight forward like:

HtmlPage.Window.Invoke("GlobalJsMethod",param1,param2);

But this works only for global methods and not for JS class methods.

In fact this will not work:

You can make a global wrapper for every class methods but you can also do something like this:

private ScriptObject _jsObject = HtmlPage.Window.Eval("JsClassInstance") as ScriptObject;
private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
                _jsObject.Invoke("JsMethod",param1,param2);
        }

that is far more elegant.

This is only a quick tip. Maybe I’ll write a more detailed post an JS-Silverlight interaction in the future.

Opml to Html converter

Yesterday I discovered that wordpress does not have a blogroll feature any more so I looked around to find a way to show my feedly subscription list in my blog.

I didn’t find anything interesting so decided to implement a simple javascipt class to convert the opml file exported from feedly to an html page so that I could easily create a wordpress page or widget.


The script is really very simple, it takes the ompl, deserialize it and create a corresponding HTML string using from a basic template defined in the JS itself. It can be certainly improved (for example adding some css class to the template for graphical customization) but, for now, it just work for my needs.

In this version you can customize the export style editing the first lines of the JS:

this.export_template = '<html><title>Opml export</title><body>{INNERHTML}</body></html>';

this.html_template = '<h1>{OPMLTITLE}</h1>n<ul>{ITEMS}</ul>';

this.rss_template = '<li>[<a href="{XMLURL}">RSS</a>] <a href="{HTMLURL}">{TITLE}</a></li>n';

this.folder_template_start = '<li>{TITLE}n<ul>n';

this.folder_template_end = '</ul></li>n';

These variables describe the export format:

  • export_template is the template for the export html page;
  • html_template is the template for the page content;
  • rss_template is the template for each RSS line;
  • folder_template_start is the template for the opening tag of RSS folder line;
  • folder_template_end is the template for the closing tag of RSS folder line.

You can find it on ghitub, under my script repository: opml.js and opml.html.

I hope it can be useful.

Silverlight datagrid RowDetails Scrollbar Issue

While developing a customer application in Silverlight 4, we find a bug in the standard datagrid control of the framework.

If you have a custom datagrid RowDetailsTemplate and this is opened and closed by a button click, you can see that, when opening the last visible row in your datagrid, the RowDetails  remains hidden, or partially hidden because the grid does not scroll automatically down to fully reveal it.


The only work-around I’ve found to avoid this misbehavior is to add the RowDetailsVisibilityChanged event to the grid and do the following:

double _rowheight = 0;
private void MyGrid_RowDetailsVisibilityChanged(object sender, DataGridRowDetailsEventArgs e)
{
if (e.Row.DetailsVisibility == System.Windows.Visibility.Visible)
{
_rowheight = e.Row.ActualHeight;
e.Row.Height = e.DetailsElement.DesiredSize.Height + _rowheight;
MyGrid.Dispatcher.BeginInvoke(delegate
{
MyGrid.Focus();
MyGrid.UpdateLayout();
MyGrid.SelectedItem = e.Row.DataContext;
MyGrid.CurrentColumn = SettingGrid.Columns[0];
MyGrid.ScrollIntoView(MyGrid.SelectedItem, MyGrid.Columns[0]);
});
}
else
{
e.Row.Height = _rowheight;
MyGrid.Dispatcher.BeginInvoke(delegate
{
MyGrid.Focus();
MyGrid.UpdateLayout();
});
}
}

As you can see the trick is to expand the grid row so that its height is equals to the height of the row details. Doing so you can than call the method ScrollIntoView to reveal the whole row details.
When the row details is closed, you have to restore the original row height.

A simple trick to fix one of the countless bugs in silverlight framework 😕 !

VPN selector


Un piccolo script utile per gestire piú connessioni VPN.
Lo script Python non fa altro che cercare tutti i file ovpn nelle sotto directory della directory passata come parametro (Documents/OpenVPN é la scelta di default).
Per il momento non é molto testato ma sembra funzionare 😉

Lo trovate qui.

Silverlight e Windows Login

In Sirverlight non esiste nativamente il modo per ottenere le informazioni sull’utente connesso a Windows. Quello che si può fare é utilizzare del codice ASP lato server e poi recuperare le informazioni da Silverlight.

Nel nostro container ASP che host il controllo Silverlight aggiungiamo qualcosa del tipo:


....

    void Page_Load()
    {
      this.UsernameField.Value = User.Identity.Name;
    }

  ...

Nel body invece mettiamo un controllo nascosto per contenere i nostri dati:


  ...

  ...

Lato Silverlight leggiamo, quando ci occorre, il volore del tag input:

public string GetUser()
{
  HtmlDocument doc = HtmlPage.Document;
  if (doc == null)
  {
    return string.Empty;
  }
  HtmlElement elm = doc.GetElementById("UserField");
  if (elm == null)
  {
    return string.Empty;
  }
  return elm.GetAttribute("value");
}

WCF ServiceHost e Cross Domain Policy

A volte capita di dover accedere con un’applicazione web a servizi hostati in un dominio esterno. Questo si risolve nella maggioranza dei casi impostando in maniera corretta il file [clientaccesspolicy.xml](http://msdn.microsoft.com/en-us/library/cc197955(VS.95).aspx "clientaccesspolicy").

Nel caso in cui però il Web Service in questione non sia hostato da un vero e proprio web server ma da un’applicazione .NET (sia essa console o form) si deve ovviare al problema della Cross Domain Policy in manera più fantasiosa ((poi dicono che gli informatici non hanno fantasia 🙂 )) .

_

_Quello che sto per descrivere é un modo semplice per simulare la presenza del file clientaccesspolicy.xml quando si ha a che fare con un ServiceHost.

Supponendo di avere già il Web Service funzionante (MyService), quello che resta da fare é far implementare ad esso un’interfaccia del tipo:

[ServiceContract]
public interface IPolicyRetriever
{
    [OperationContract]
    [WebGet(UriTemplate = "/clientaccesspolicy.xml")]
    Stream GetSilverlightPolicy();
}

Inquesta interfaccia specifichiamo che il servizio deve rispondere quando viene interrogato l’Uri /clientaccesspolicy.xml.

Il gioco è fatto.

Basta ora implementare il service in un modo simile a questo:

public Stream GetSilverlightPolicy()
{
       string result = @

                              ";
      WebOperationContext.Current.OutgoingResponse.ContentType = "application/xml";
      return new MemoryStream(Encoding.UTF8.GetBytes(result));
}

e creare il ServiceHost dove aggiungere i due endpoint.

class Program
    {
        static void Main(string[] args)
        {
            Uri baseAddress = new Uri("http://localhost:9090");
            // Create the ServiceHost.
            using (ServiceHost host = new ServiceHost(typeof(MyService), baseAddress))
            {
                // Enable metadata publishing.
                ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
                smb.HttpGetEnabled = true;
                smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
                host.Description.Behaviors.Add(smb);
                host.AddServiceEndpoint(typeof(IMyService), new BasicHttpBinding(), new Uri("http://localhost:9090/myservice.svc"));

                host.AddServiceEndpoint(typeof(IPolicyRetriever), new WebHttpBinding(), "").Behaviors.Add(new WebHttpBehavior());

                host.Open();
                Console.ReadLine();
                host.Close();
            }
        }
    }

Ecco fatto; il nostro client potrà accedere al WebService senza problemi.

Trovare ed eliminare record (semi-)duplicati in SQL

Lo ammetto: non é certo la cosa più complicata del mondo eliminare le righe duplicate in un database; quando serve però non viene mai in mente un modo per farlo.
Questo post lo categorizzo quindi come mio promemoria!

Perché (semi-)duplicati?
Parto dall’esempio pratico: aggiungere una chiave ad una tabella già piena di dati.
Ovviamente, per la legge di Murphy, i valori dei campi che dovrebbero diventare chiave non saranno mai tutti diversi. Voglio quindi eliminare dalla tabella i record con chiavi uguali, preservandone solo una copia per ognuno.

Poniamo che la nostra tabella di chiami table1 con campi field1,field2,field3 (la fantasia nel dare i nomi é il mio forte). Vogliamo far diventare field1 e field2 chiave primaria. Per eliminare i duplicati eseguiamo:

SELECT * FROM db.table1 as t2 WHERE (t2.field1,t2.field2,t2.field3) not in ( SELECT t1.field1,t1.field2, min(t1.field3) FROM db.table1 as t1 group by t1.field1,t1.field2)

Fatto! Come preannunciato niente di emozionante… 😉

Ovviamente la regola min(t1.field3) puo' essere cambiata a piacimento per conservare il record piu' conveniente ai fini dell’applicazione.