问题
I have some large texts in a Windows phone 8 app and I want there to be e-mail links inside, something like a mailto feature. Here's a part of the code:
<phone:PivotItem Header="μέλη ΔΕΠ">
<ScrollViewer>
<StackPanel>
<TextBlock TextWrapping="Wrap">
<Run Text="John Doe"/>
<LineBreak/>
<Run Text="503 (Building DS 126)"/>
<LineBreak/>
<Run Text="tel.: +30 210-1234567"/>
<LineBreak/>
<Run Text="e-mail: johndoe@uni.gr"/>
</TextBlock>
</StackPanel>
</ScrollViewer>
</phone:PivotItem>
I would like the "e-mail: johndoe@uni.gr" to be clickable and open the mail app on the phone.
There are quite a few situations like this in my code with emails in much larger text and that's why I use the <TextBlock><Run Text=".."/><LineBreak/>...
format.
Now I know I can't use a hyperlink button inside the <Run Text=".."/>
so any suggestions?
回答1:
HyperlinkButton is good if you want a hyperlink in your UI, but if you want a hyperlink embedded in a run of text you should use RichTextBox with a Hyperlink:
<RichTextBox TextWrapping="Wrap">
<Paragraph>
<Run Text="John Doe" />
<LineBreak />
<Run Text="503 (Building DS 126)" />
<LineBreak />
<Run Text="tel.: +30 210-1234567" />
<LineBreak />
<Hyperlink Click="Hyperlink_OnClick">e-mail: johndoe@uni.gr</Hyperlink>
</Paragraph>
</RichTextBox>
And then use the handler from Julien's answer:
private void Hyperlink_OnClick(object sender, RoutedEventArgs e) {
EmailComposeTask emailComposeTask = new EmailComposeTask();
emailComposeTask.Subject = "message subject";
emailComposeTask.Body = "message body";
emailComposeTask.To = "johndoe@uni.gr";
emailComposeTask.Show();
}
Good luck!
回答2:
You could also do the following:
Overload MapUri() as it is done for URI-Associations of an App and never worry about handling any click events anymore.
XAML:
<Hyperlink NavigateUri="tel:0800-555-1234'}">call 0800-555-1234</Hyperlink>
<Hyperlink NavigateUri="mailto:you@your-domain.com'}">e-Mail you@your-domain.com</Hyperlink>
C# App.xaml.cs
private void InitializePhoneApplication() {
...
//get ready for URI association
RootFrame.UriMapper = new AssociationUriMapper();
}
C#
class AssociateioniMapper : UriMapperBase
{
public override Uri MapUri(Uri uri)
{
tempUri = System.Net.HttpUtility.UrlDecode(uri.ToString());
Uri retUri = uri;
//handle known uri schemes
if (uriUsesKnownScheme(uri))
{
Debug.WriteLine("Known Uri scheme: " + uri.Scheme);
NavigateConsideringKnownScheme(uri);
retUri = null;
}
}
private bool uriUsesKnownScheme(Uri uri)
{
try
{
switch (uri.Scheme)
{
case "http":
case "https":
case "mailto":
case "tel":
return true;
default:
return false;
}
}
catch (Exception)
{
//uri does not have a scheme
return false;
}
}
private void NavigateConsideringKnownScheme(Uri uri)
{
try
{
switch (uri.Scheme)
{
case schemeHttp:
case schemeHttps:
//open URI in IE
WebBrowserTask webBrowserTask = new WebBrowserTask();
webBrowserTask.Uri = uri;
webBrowserTask.Show();
break;
case schemeMailto:
//initiate eMail task
if (! string.IsNullOrWhiteSpace(uri.Query))
handleMailtoUrl_Query(uri.Query);
else
handleMailtoUrl_To(uri.OriginalString.Replace("mailto:", string.Empty));
break;
case schemeTel:
//initiate phonecall task
handleTel(uri.PathAndQuery);
break;
default:
break;
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
private void handleTel(string parameter)
{
try
{
string p = parameter as string;
string number = p;
string displayName = string.Empty;
number = Regex.Replace(number, "[^+0-9]", "");
startPhoneCall(number, displayName);
}
catch (Exception e)
{
throw e;
}
}
private void startPhoneCall(string number, string displayName)
{
try
{
PhoneCallTask phoneCallTask = new PhoneCallTask();
phoneCallTask.PhoneNumber = number;
if (!string.IsNullOrWhiteSpace(displayName))
{
phoneCallTask.DisplayName = displayName;
}
phoneCallTask.Show();
}
catch (Exception e)
{
MessageBox.Show(LocalizationHelper.GetString("ContactPhonecallError"));
}
}
private void handleMailtoUrl_Query(string query)
{
//handle subject, to, body and other parameters if required
}
private void handleMailtoUrl_To(string to)
{
try
{
EmailComposeTask emailComposeTask = new EmailComposeTask();
emailComposeTask.To = to;
emailComposeTask.Show();
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
}
}
}
回答3:
Add an HyperLinkButton :
<HyperlinkButton Name="emailLink" Content="johndoe@uni.gr" Click="EmailLink_Click" />
and in EmailLink_Link, you can launch the EmailComposeTask (http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh394003(v=vs.105).aspx)
private void EMailLink_Click(object sender, RoutedEventArgs e)
{
EmailComposeTask emailComposeTask = new EmailComposeTask();
emailComposeTask.Subject = "message subject";
emailComposeTask.Body = "message body";
emailComposeTask.To = emailLink.Content;
emailComposeTask.Show();
}
回答4:
Even easier:
XAML:
<HyperlinkButton Content="yourname@yourdomain.com" Click="HyperlinkButton_Click"/>
Click event handler:
private void HyperlinkButton_Click(object sender, RoutedEventArgs e)
{
Windows.System.Launcher.LaunchUriAsync(new Uri("mailto:yourname@yourdomain.com"));
}
Besides opening your email app, there's a lot more you can do with the Launcher: http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj662937(v=vs.105).aspx
来源:https://stackoverflow.com/questions/15142924/how-to-have-an-email-link-inside-a-text-in-xaml