我正在尝试捕获动态生成的RichTextBlock中的超链接的单击事件。
我动态生成一个richtextblock的内容,然后用XamlReader应用它们。内容可能会有很大的不同,所以我不能手动解析xaml并在这一点上挂接事件。
我的基本想法是,一旦richtextblock被加载,找到其中的所有超链接,并在那里挂接它们的click事件。这是我当前的代码:
public class HookUpEvents()
{
foreach (var child in FindVisualChildren<Hyperlink>(richtxtblock))
{
child.Click += MyFunction;
}
}
public static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
{
if (depObj != null)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
if (child != null && child is T)
{
yield return (T)child;
}
foreach (T childOfChild in FindVisualChildren<T>(child))
{
yield return childOfChild;
}
}
}
}显然,它不起作用。看起来FindVisualChildren函数没有返回任何超链接。关于如何实现这一点有什么想法吗?
发布于 2021-01-16 20:47:09
嗯,我肯定去晚了,但RichTextBlock大多数时候都不会把他的Blocks和他们的Inlines放在VisualTree里。要找到所有Inline-based elements (Run,Span,Bold etc.),您需要遍历所有内容,访问每个Block和后续的Inline。我建议这样做:
public static IEnumerable<T> GetAllTextElements<T>(this RichTextBlock rtb) where T : TextElement
{
var result = new List<T>();
var blocks = rtb.Blocks;
foreach (var block in blocks)
{
if (block is T)
{
result.Add(block as T);
continue;
}
var inlines = ((Paragraph)block).Inlines;
var res = TraverseInline<T>(inlines);
if (res != null && res.Any())
result.AddRange(res);
}
return result;
}
private static IEnumerable<T> TraverseInline<T>(IEnumerable<Inline> inlines) where T : TextElement
{
var result = new List<T>();
foreach (var item in inlines)
{
if (item is T)
{
result.Add(item as T);
continue;
}
else if (item is Span) // first Inline derived class to have own `Inlines`
{
var spanItem = item as Span;
var spanInlines = spanItem.Inlines;
var results = TraverseInline<T>(spanInlines);
if (results != null && results.Any())
result.AddRange(results);
}
}
return result;
}因此,您可以使用它查找任何TextElement-derived项目。用法类似于:
var textHyperlinks = myRichTextBlock.GetAllTextElements<Hyperlink>();只要不使用InlineUIContainer,就可以做到这一点。这种类型的Inline的行为不同,因为您可以将任何UIElement-based放在它的Child属性中。在这种情况下,您的初始方法应该是可行的。
发布于 2017-04-07 02:42:35
这里有几件事:
如果您试图查找RichTextBlock内部的超链接,它的类型是: Windows.UI.Xaml.Documents.Hyperlink。不是HyperLinkButton的类型。
可以将Click事件处理程序放在文本中,然后在代码隐藏文件中提供处理程序方法。如果动态生成如下所示的文本:
<Paragraph>
Text with a
<Hyperlink x:Name="link" Click="link_Click">link.</Hyperlink>
</Paragraph>将其提供给XamlReader,并将以下代码放入您的代码隐藏文件中:
private void link_Click(Windows.UI.Xaml.Documents.Hyperlink sender, Windows.UI.Xaml.Documents.HyperlinkClickEventArgs args)
{
Debug.WriteLine("Handle link click, by: " + sender.Name);
}然后,它应该在运行时正确连接。您可以在Click事件处理程序上做任何您想做的事情。即使有多个链接,您也可以对它们进行不同的命名,只需使用一个单击处理程序即可处理。
https://stackoverflow.com/questions/43259811
复制相似问题