Click here to Skip to main content
15,880,405 members
Please Sign up or sign in to vote.
4.10/5 (3 votes)
See more:
Hi,

I have following problem:

In an Silverlight 5 Application (IE9, VS2010, Hosted in WebApplication) I created an innocent HyperlinkButton to let the user send an email. But whatever I do this command always opens another browser-window/tab (the mail-client is opened too - thats fine and what I expect to happen).

The Hyperlink-Button is defined like this (nothing special):

HTML
<HyperlinkButton x:Name="TestLink"                     
                     Content="TestLink"                     
                     Click="TestLink_Click">
</HyperlinkButton>


here is the code for the Click-Handler

C#
private void TestLink_Click(object sender, RoutedEventArgs e)
{
    System.Windows.Browser.HtmlPage.Window.Navigate(
        new Uri("mailto:test@test.com")); // I use a real email-address 
}


I also used another approach by evaluating a javascript - same result (the additional browser window opens)

C#
public void MailTo(string toEmail, string subject, string body)
{
    String strCmd = String.Format("window.open('mailto:{0}?subject={1}&body={2}');",
    toEmail, subject, body);
    HtmlPage.Window.Eval(strCmd );
} 


Other things I tried: Using HyperlinkButton's TargetName property with values "", "_self", "_blank" and the Name of a Navigation.Frame I host on the same XAML page -> same result (and I also tried to set these values with the matching Navigate overload.)

And of course if I tried the most obvious thing: setting HyperlinkButton's NavigateUri property in XAML - it even didn't open the mail-client...

I hope one of you knows about this problem, and I have not to waste more hours for such a simple thing...
Posted
Updated 14-Feb-12 3:55am
v3
Comments
johannesnestler 14-Feb-12 11:27am    
no one? even google doesn't seem to know it..
Brendon Frater 10-May-12 17:40pm    
I have been experiencing this exact same issue with Silverlight 4. So far no solution.

I finally found a solution. to this issue.
Instead of using Window.Navigate, use javascript location.href.


C#
private void TestLink_Click(object sender, RoutedEventArgs e)
{
    //Only run the click event if in browser because this will not work OOB
    if (Application.Current.IsRunningOutOfBrowser)
        return;

    var cmd = String.Format("location.href='mailto:test@test.com?subject=blah&body=something';",

    HtmlPage.Window.Eval(cmd);
}



Note: This wont work OOB as HtmlPage is not available, however the default behaviour for the mailto works as it should so in your constructor only bind the NavigateUri if OOB.


In my project I created a control to wrap all this up so I could bind the email, subject and body in xaml.

Here it is..

C#
/// <summary>
/// This component allows us to display an email address as a hyperlink that the user can click and it will open a new email window
/// in their default email client.  It can handle in browser and out of browser
/// It gets around the issue which we previously were experiencing where a new browser window would open and an email window.
/// </summary>
public class MailToButton : HyperlinkButton
{
    /// <summary>
    /// Email dependency property
    /// </summary>
    public static readonly DependencyProperty EmailProperty = DependencyProperty.Register("Email",
                                                                                          typeof(string),
                                                                                          typeof(
                                                                                              MailToButton
                                                                                              ), null);
    /// <summary>
    /// Email Address
    /// </summary>
    public object Email
    {
        get { return GetValue(EmailProperty); }
        set { SetValue(EmailProperty, Convert.ToString(value)); }
    }

    /// <summary>
    /// Subject dependency property
    /// </summary>
    public static readonly DependencyProperty SubjectProperty = DependencyProperty.Register("Subject",
                                                                                          typeof(string),
                                                                                          typeof(
                                                                                              MailToButton
                                                                                              ), null);
    /// <summary>
    /// Email Subject
    /// </summary>
    public object Subject
    {
        get { return GetValue(SubjectProperty); }
        set { SetValue(SubjectProperty, Convert.ToString(value)); }
    }

    /// <summary>
    /// Body dependency property
    /// </summary>
    public static readonly DependencyProperty BodyProperty = DependencyProperty.Register("Body",
                                                                                          typeof(string),
                                                                                          typeof(
                                                                                              MailToButton
                                                                                              ), null);

    /// <summary>
    /// Hide the NavigateUri property in the base, we will set this manually in code.
    /// </summary>
    public new Uri NavigateUri { get; set; }

    /// <summary>
    /// Email Body
    /// </summary>
    public object Body
    {
        get { return GetValue(BodyProperty); }
        set { SetValue(BodyProperty, Convert.ToString(value)); }
    }

    /// <summary>
    /// Constructor
    /// </summary>
    public MailToButton()
    {
        Loaded += MailToButton_Loaded;
        Click += MailToButtonClicked;

    }

    private void MailToButton_Loaded(object sender, RoutedEventArgs e)
    {
        //Only bind the NavigateUrl when OOB as this method does not work in browser
        if (Application.Current.IsRunningOutOfBrowser)
            base.NavigateUri = new Uri(BuildMailToString());
    }

    private void MailToButtonClicked(object sender, RoutedEventArgs e)
    {
        //Only run the click event if in browser because this will not work OOB
        if (Application.Current.IsRunningOutOfBrowser)
            return;

        if (string.IsNullOrEmpty(Convert.ToString(Email)))
            return;

        HtmlPage.Window.Eval(BuildMailToString());
    }

    /// <summary>
    /// Constructs a MailTo string using the email, subject and body.  It url encodes the email, subject and body
    /// </summary>
    /// <returns>A mailto string</returns>
    private string BuildMailToString()
    {
        var email = HttpUtility.UrlEncode(Convert.ToString(Email));
        var subject = HttpUtility.UrlEncode(Convert.ToString(Subject));
        var body = HttpUtility.UrlEncode(Convert.ToString(Body));

        var sb = new StringBuilder();
        sb.AppendFormat("location.href='mailto:{0}?", email);

        if (!string.IsNullOrEmpty(subject))
            sb.AppendFormat("subject={0}", subject);

        if (!string.IsNullOrEmpty(body))
        {
            if (!string.IsNullOrEmpty(subject))
                sb.Append("&");

            sb.AppendFormat("body={0}", body);
        }
        sb.Append("'");

        return sb.ToString();
    }

}
 
Share this answer
 
v2
Comments
johannesnestler 14-May-12 7:09am    
Great! Thank you for your solution (and the Control)!
And you didn't think to look here[^]? And here[^] ...
 
Share this answer
 
v2
Comments
johannesnestler 14-Feb-12 15:18pm    
Hi Richard,

Thank you for your links - And suprise! I thought to hit F1 in VS. - But this doesn't solve my problem. If you can enlighten me what specific part of the docu regarding my problem I have missed... Maybe I didn't formulate the question good enough? - Always problems with my english...
Richard MacCutchan 14-Feb-12 15:39pm    
You need to use the overload of the Navigate() method that allows you to specify where the link should be opened. The default is to open in a new window, but using the keyword "_self" will open in the current window. You may need to read through the documentation more closely than I did.
johannesnestler 15-Feb-12 7:23am    
Hi Richard,

Thank you again, but if you read my question closely I already tried to use _self. The problem is I'm not in a "Webpage" I'm in a Silverlight 5 Application which runs inside the browser, hosted in an asp.net 4 webapplication - so it seems to open a new browser window/tab even with _self (I host a Navigation.Frame control, but if I use it as target it throws an Invalid URI exceptions, seems it can not handle mailto: - but no word in the docu about it...) After you comment I read all the docus again - and tried all again - always the same result. If you have any other ideas, please let me know!
Richard MacCutchan 15-Feb-12 9:48am    
Yes, I apologise for that, not sure how I missed it first time round. Silverlight seems to have its own rules for some things, but I could not find any other suggestions on this issue. It may be that opening a link in the same window would somehow destroy the Silverlight app and is thus prohibited.
johannesnestler 15-Feb-12 10:16am    
Anyway, thank you for trying to help! - If I finally find a solution I'll update this question.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900