Xaml Can';无法获得我想要的文本包装行为

Xaml Can';无法获得我想要的文本包装行为,xaml,silverlight,text,silverlight-2.0,Xaml,Silverlight,Text,Silverlight 2.0,我很难让Silverlight 2.0完全按照我想要的方式布局文本。我想要带换行符和嵌入链接、带换行符的文本,就像网页中的HTML文本一样 这是我最近的一次: <UserControl x:Class="FlowPanelTest.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/x

我很难让Silverlight 2.0完全按照我想要的方式布局文本。我想要带换行符和嵌入链接、带换行符的文本,就像网页中的HTML文本一样

这是我最近的一次:

<UserControl x:Class="FlowPanelTest.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:Controls="clr-namespace:Microsoft.Windows.Controls;assembly=Microsoft.Windows.Controls" 
    Width="250" Height="300">
    <Border BorderBrush="Black" BorderThickness="2" >
      <Controls:WrapPanel> 
      <TextBlock x:Name="tb1" TextWrapping="Wrap">Short text. </TextBlock>
      <TextBlock x:Name="tb2" TextWrapping="Wrap">A bit of text. </TextBlock>
      <TextBlock x:Name="tb3" TextWrapping="Wrap">About half of a line of text.</TextBlock>
      <TextBlock x:Name="tb4" TextWrapping="Wrap">More than half a line of longer text.</TextBlock>
      <TextBlock x:Name="tb5" TextWrapping="Wrap">More than one line of text, so it will wrap onto the  following line.</TextBlock>
      </Controls:WrapPanel>
      </Border>
</UserControl>
使用带边距的空文本块将以下内容分隔到下一行上

我还在想这个。 如何计算换行块的正确宽度,以将后续内容强制添加到后续行上?太短,以下内容仍将位于同一行的右侧。如果太长,“换行符”将位于下一行,后面有内容。调整控件大小时,必须调整打断的大小

这方面的一些代码是:

    TextBlock lineBreak = new TextBlock();
    lineBreak.TextWrapping = TextWrapping.Wrap;
    lineBreak.Text = " ";
    // need adaptive width 
    lineBreak.Margin = new Thickness(0, 0, 200, 0);

一个非常有趣的问题。您可能需要创建自己的自定义控件来处理这种类型的布局。您可以使用跑步,但在每次跑步的顶部覆盖一个透明的画布,以便处理与该跑步相关的点击事件。一点也不容易解决,但我认为这是可能的


请告诉我你带了什么。

为什么不能使用跑步

使用“运行”将所有不包含事件的值合并,然后将包含事件的值分解为自己的文本块,冲洗并重复

在我看来,您应该能够通过正则表达式和一些循环来实现这一点。 查看Jesse Liberty在wrap panel上的帖子,看看这是否会引发任何想法。


hth

您可以尝试仅在TextBlock内部使用运行,并对整个TextBlock使用一个单击处理程序。然后,处理程序可以使用click事件的坐标定位源运行,找出它是否是一个链接(作为链接的每个运行可以有一个特定的x:Name,或者您甚至可以派生自己的运行),并为该链接调用正确的功能


我从未尝试过,但这是我试图解决问题的方法。

我认为最好的方法是将每个单词都作为文本块,然后将这些单词附加到特定部分所需的正确事件处理程序。这将为您提供所需的包装,对于第一个单词的缩进,您可以设置它的左边距

请参阅本文中的一个例子,在这个例子中,文本和包装面板完成了类似的操作。

虽然没有IsMouseOver类型属性,但您可以使用VisualTreeHelper.FindElementsInHostCoordinates()查看。

我不确定您是否检查了注释上的注释,因为您没有解决我在您的注释中说的一些问题。无法使用VisualTreeHelper.FindElementsInHostCoordinates()查找运行的原因是,它只返回UIElements,而运行不是UIElements。如果你把这个方法和不使用任何跑步的建议结合起来,那么你应该很好,对吧

事实上,每个单词作为一个文本块并不是一个很糟糕的“黑客”,你可以通过将分线分割成它们自己的文本块,并为这些文本块指定一个等于环绕面板宽度的宽度或边距,这将迫使它们坐在自己的行上,从而绕过换行符的问题。绝对不是最理想的解决方案,但我还没有看到任何其他有希望的解决方案

这样行吗? 试试这个:


Silverlight的HtmlTextBlock。这不是一个很好的概念,但它可能是一个很好的起点

根据我的发现,我将对我自己的问题给出一些答案:

1)您可以在完整的fat桌面WPF中轻松完成此操作,其中包含一个包含段落、超链接、运行和相关对象的流程文档

这就是我现在正在做的,我不再试图在Silverlight中解决这个问题

2)使用Silverlight 4在Silverlight 2或3中无法执行此操作。然而,Silverlight 4有一个RichTextArea控件,当它是只读的时,它支持这种带有内联超链接的流布局显示,因此它就像是WPF中的FlowDocument和相关类的精简版本。Silverlight 4还允许嵌入式Web浏览器控件显示HTML内容,前提是您可以使其在Windows版本(即IE版本)以及Mac和其他平台上看起来相同


3)您可能可以在Silverlight(任何版本)中执行类似的操作,方法是构建一个HTML字符串并将其注入DOM中,以在Silverlight控件之外的页面部分显示它。这听起来完全可行,但在我看来,太聪明了。

我对“有趣的问题”这个短语有一种不好的感觉。我正在尝试这样做,但你如何定位跑步?你有点击事件的坐标,但我不知道如何找到跑步的边界。我已经在上面的问题中解决了这个问题。你可以通过将换行符分成一个文本块并将换行符文本块的左/右边距或宽度设置为换行符的宽度来解决这个问题。迫使他们站在自己的立场上。不完美,但这可能是你能做的最好的。好主意,我没有;我不知道那个函数。我已经在上面讨论过了。我还没有时间尝试这个-上面的评论。没有。这只是将每个单词放入自己的文本块的另一种情况。如问题中所述,它在换行符和段落符方面存在严重问题。此外,请将该示例中的链接文本更改为“此控件根本不包装具有长文本的链接”。链接现在开始在一个新的行时,它不应该。WrapPanel没有办法将链接分解成单独的单词。如果链接带下划线,那就不好了。或者将链接更改为“[link=”“target=“\u blank”]敏捷的棕色狐狸跳过了松懈的狗,敏捷的棕色狗跳过了懒惰的狗[/link]”-链接按钮根本无法包装。这是一个很好的控件,如果
private void theText_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
    // get the elements under the click
    UIElement uiElementSender = sender as UIElement;
    Point clickPos = e.GetPosition(uiElementSender);
    var UiElementsUnderClick = VisualTreeHelper.FindElementsInHostCoordinates(clickPos, uiElementSender);

    // show the controls
    string outputText = "";
    foreach (var uiElement in UiElementsUnderClick)
    {
        outputText += uiElement.GetType().ToString() + "\n";
    }
    this.outText.Text = outputText;
}
    TextBlock lineBreak = new TextBlock();
    lineBreak.TextWrapping = TextWrapping.Wrap;
    lineBreak.Text = " ";
    // need adaptive width 
    lineBreak.Margin = new Thickness(0, 0, 200, 0);