我在WPF应用程序中使用自定义文本块,当我在WPF Windows中使用它时,它工作得很好,但当我在WPF页面中使用它时,它会产生问题。当我点击自定义控件中的链接时,它会浏览链接并显示在浏览器中,但是WPF页面也会导航回另一个WPF页面(第一页)
namespace Dtwitter.Controls
{
public class TweetTextBlock : TextBlock
{
public TweetTextBlock()
{
}
#region Dependency properties
public string TweetText
{
get { return (string)GetValue(TweetTextProperty); }
set { SetValue(TweetTextProperty, value); }
}
// Using a DependencyProperty as the backing store for TweetText. This enables animation, styling, binding, etc...
public static readonly DependencyProperty TweetTextProperty =
DependencyProperty.Register("TweetText", typeof(string), typeof(TweetTextBlock),
new FrameworkPropertyMetadata(string.Empty, new PropertyChangedCallback(OnTweetTextChanged)));
#endregion
private static void OnTweetTextChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
string text = args.NewValue as string;
if (!string.IsNullOrEmpty(text))
{
TweetTextBlock textblock = (TweetTextBlock)obj;
textblock.Inlines.Clear();
textblock.Inlines.Add(" ");
string[] words = Regex.Split(text, @"([ (){}[]])");
string possibleUserName = words[0].ToString();
if ((possibleUserName.Length > 1) && (possibleUserName.Substring(1, 1) == "@"))
{
textblock = FormatName(textblock, possibleUserName);
words.SetValue("", 0);
}
foreach (string word in words)
{
// clickable hyperlinks
if (UrlShorteningService.IsUrl(word))
{
try
{
Hyperlink link = new Hyperlink();
link.NavigateUri = new Uri(word);
link.Inlines.Add(word);
link.Click += new RoutedEventHandler(link_Click);
link.ToolTip = "Open link in the default browser";
textblock.Inlines.Add(link);
}
catch
{
//TODO:What are we catching here? Why? Log it?
textblock.Inlines.Add(word);
}
}
// clickable @name
else if (word.StartsWith("@"))
{
textblock = FormatName(textblock, word);
}
// clickable #hashtag
else if (word.StartsWith("#"))
{
string hashtag = String.Empty;
Match foundHashtag = Regex.Match(word, @"#(w+)(?<suffix>.*)");
if (foundHashtag.Success)
{
hashtag = foundHashtag.Groups[1].Captures[0].Value;
Hyperlink tag = new Hyperlink();
tag.Inlines.Add(hashtag);
string hashtagUrl = "http://search.twitter.com/search?q=%23{0}";
// The main application has access to the Settings class, where a
// user-defined hashtagUrl can be stored. This hardcoded one that
// is used to set the NavigateUri is just a default behavior that
// will be used if the click event is not handled for some reason.
tag.NavigateUri = new Uri(String.Format(hashtagUrl, hashtag));
tag.ToolTip = "Show statuses that include this hashtag";
tag.Tag = hashtag;
tag.Click += new RoutedEventHandler(hashtag_Click);
textblock.Inlines.Add("#");
textblock.Inlines.Add(tag);
textblock.Inlines.Add(foundHashtag.Groups["suffix"].Captures[0].Value);
}
}
else
{
textblock.Inlines.Add(word);
}
}
textblock.Inlines.Add(" ");
}
}
public static TweetTextBlock FormatName(TweetTextBlock textblock, string word)
{
string userName = String.Empty;
string firstLetter = word.Substring(0, 1);
Match foundUsername = Regex.Match(word, @"@(w+)(?<suffix>.*)");
if (foundUsername.Success)
{
userName = foundUsername.Groups[1].Captures[0].Value;
Hyperlink name = new Hyperlink();
name.Inlines.Add(userName);
name.NavigateUri = new Uri("http://twitter.com/" + userName);
name.ToolTip = "View @" + userName + "'s recent tweets";
name.Tag = userName;
name.Click += new RoutedEventHandler(name_Click);
if (firstLetter != "@")
textblock.Inlines.Add(firstLetter);
textblock.Inlines.Add("@");
textblock.Inlines.Add(name);
textblock.Inlines.Add(foundUsername.Groups["suffix"].Captures[0].Value);
}
return textblock;
}
static void link_Click(object sender, RoutedEventArgs e)
{
try
{
System.Diagnostics.Process.Start(((Hyperlink)sender).NavigateUri.ToString());
}
catch
{
//TODO: Log specific URL that caused error
MessageBox.Show("There was a problem launching the specified URL.", "Error", MessageBoxButton.OK, MessageBoxImage.Exclamation);
}
}
}
}
更改链接点击方法为
static void link_click(Object sender, RequestNavigateEventArgs e) {
try {
System.Diagnostics.Process.Start(e.Uri.ToString());
} catch {
//TODO: Log specific URL that caused error
MessageBox.Show("There was a problem launching the specified URL.", "Error", MessageBoxButton.OK, MessageBoxImage.Exclamation);
} finally {
e.Handled = true;
}
}
更改
link.Click+=new RoutedEventHandler(link_Click);
link.RequestNavigate+=new RequestNavigateEventHandler(link_Click);
在link_click中设置e.Handled=true
来标记你已经处理了链接点击,以防止框架进一步处理你的链接点击。
或者你可以把Hyperlink的TargetName属性设置为"_blank"而不需要进程启动命令
下面的代码应该使它在两种情况下(Page和Window)都以相同的方式工作....
尝试在web浏览器中按下鼠标打开超链接对象的超链接。
Process.Start((e.OriginalSource as Hyperlink).NavigateUri.ToString());
e.Handled = true;
如果有帮助请告诉我