Ostatnio w mojej pracy z Silverlightem i kontrolkami Telerikowymi natknąłem się na pewny issue związany z linkami typu mailto: i callto:. Czym są te linki? To zwykłe linki, z tą tylko różnicą, że przenoszą do naszego klienta poczty w przypadku mailto, lub do np. skype w wypadku callto. Okazuje się jednak, że nie do końca są one obsługiwane przez Silverlighta. Nawet w najnowszej, 4 już wersji. Na szczęście da się to obejść :) Poniżej metoda poradzenia sobie w przypadku standardowych linków oraz linków w Gridzie.

Zwykłe linki

Aby zwykłe linki prowadziły do Skype’a, a nie wywalały całej formatki, należy wywoływać przy każdym kliknięciu w ten link taką oto metodkę:

private void hyperlink_Click(object sender, RoutedEventArgs e) 
{ 
	HyperlinkButton hlink = sender as HyperlinkButton; 
    if (hlink.NavigateUri.AbsoluteUri.StartsWith("callto:")) 
    { 	System.Windows.Browser.HtmlPage.Window.Navigate(hlink.NavigateUri); 
    } 
}

Tego typu przekierowania działają bez zarzutu, więc możemy to z powodzeniem wykorzystać. Należy ponadto pamiętać, by cały link był w pełni poprawny. Tzn. np. polski numer pisany ze spacjami, nawiasami, myślnikami i innymi dziwnymi rzeczami jest niepoprawny. Należy więc numer taki wyczyścić i zostawić ostateczną formę: +48123456789. Zwykłe linki nie mają większych problemów z mailto: więc tę część zostawimy do naszego Grida:

Grid

W przypadku Grida nie jest już tak miło – zarówno linki mailto, jak i callto nie działają (w szczególności po ostatniej aktualizacji ze strony Telerika); dodatkowo trudniej jest nieco poradzić sobie z tym problemem. Na szczęście problem można rozwiązać poprzez dodanie własnego typu kolumn i zastąpieniu standardowego CellTemplate przez nasz customowy. Przykładowe rozwiązanie dla kolumny zawierającej klikalne numery telefonów:

public class PhoneGridColumn : GridViewColumn
    {
        public override FrameworkElement CreateCellElement(GridViewCell cell, object dataItem)
        {
            HyperlinkButton hlink = cell.Content as HyperlinkButton;
            if (hlink == null)
            {
                hlink = new HyperlinkButton();
                hlink.Click += new RoutedEventHandler(hyperlink_Click);
                string value = dataItem[this.UniqueName] as String;
                hlink.NavigateUri = new Uri("callto:" + value);
                hlink.Content = value;
            }
            return hlink;
        }

        protected void hyperlink_Click(object sender, RoutedEventArgs e)
        {
            HyperlinkButton hlink = sender as HyperlinkButton;
            if (hlink.NavigateUri.AbsoluteUri.StartsWith("callto:"))
            {  System.Windows.Browser.HtmlPage.Window.Navigate(hlink.NavigateUri);
            }
        }
    }

Dzięki temu z jednej strony nie trzeba dodawać numerów z kłopotliwym callto: na początku, to dodatkowo można tutaj dodać jeszcze parsowanie i poprawianie wprowadzonego numeru, oraz zagwarantowane jest poprawne działanie kliknięcia w tenże link kontaktowy.