【问题标题】:Clicking on a TextBlock in WPF richtextbox单击 WPF 富文本框中的 TextBlock
【发布时间】:2013-07-29 13:34:19
【问题描述】:

我有一个这样的流文档:

var mcFlowDoc = new FlowDocument();
var para = new Paragraph();
para.Inlines.Add(textBlock1);
para.Inlines.Add(textBlock2);
para.Inlines.Add(textBlock3);
mcFlowDoc.Blocks.Add(para);
richTextBox1.Document = mcFlowDoc;

我需要一个事件来触发鼠标点击文本块:

    <RichTextBox Margin="10,10,230,12" Name="richTextBox1" FontFamily="Simplified Arabic" FontSize="16" IsReadOnly="True" IsReadOnlyCaretVisible="False" ForceCursor="False" FlowDirection="RightToLeft" VerticalScrollBarVisibility="Auto">
        <RichTextBox.Resources>
            <Style TargetType="Run">
                <EventSetter Event="MouseLeftButtonDown" Handler="Run_Click" />
            </Style>
            <Style TargetType="TextBlock">
                <EventSetter Event="MouseLeftButtonDown" Handler="TextBlock_Click" />
            </Style>
        </RichTextBox.Resources>
    </RichTextBox>

void TextBlock_Click(object sender, MouseButtonEventArgs e)
        {
            TextBlock tb = sender as TextBlock;
        }

Run 的事件处理程序被调用并正常工作 (Changing inline in flowdocument),但 TextBlock 的事件处理程序不是。

我做错了什么? 谢谢

【问题讨论】:

  • 您将 FlowDocument 分配给richTextBox。你确定richTextBox1 也有带有TextBlocks 的FlowDocument 吗?
  • 是的,这就是我使用的:textBlock1 = new TextBlock(run1));
  • 我的意思是你可能有两个 RichTextBox。一个名为richTextBox,带有FlowDocument,另一个在XAML 中声明,名为richTextBox1,没有内容但有事件处理。
  • 对不起,都是richTextBox1。我刚刚编辑了问题。

标签: c# wpf richtextbox textblock


【解决方案1】:

引用MSDN:

重要

RichTextBox 具有对冒泡 MouseUp 和 MouseDown 事件的内置处理。因此,将永远不会调用从 RichTextBox 侦听 MouseUp 或 MouseDown 事件的自定义事件处理程序。如果您需要响应这些事件,请改为侦听隧道 PreviewMouseUp 和 PreviewMouseDown 事件,或者使用 HandledEventsToo 参数注册处理程序(后一个选项只能通过代码获得)。不要将事件标记为已处理,除非您有意禁用 RichTextBox 对这些事件的本机处理,并注意这会对控件的 UI 产生显着影响。

所以你需要寻找替代品。我可以推荐一些。

首先,您可以为所有RichTextBox 设置一个事件处理程序PreviewMouseDown

<RichTextBox PreviewMouseDown="TextBlock_Click" ... />

其次,使用BlockUIContainer 并将文本放在内容按钮中。例如:

<Paragraph FontSize="18">Flow Example</Paragraph>

<BlockUIContainer>
  <Button x:Name="MyButton" ClickMode="Release" Click="Button_Click">
    <TextBlock Margin="4" TextWrapping="Wrap">
      Some text
    </TextBlock>
  </Button>
</BlockUIContainer>

第三,您可以像这样为Paragraph 设置事件处理程序:

var para = new Paragraph();
para.Inlines.Add(textBlock1);

para.MouseLeftButtonDown += new MouseButtonEventHandler(TextBlock_Click);

Edit

引用亚当·内森的书WPF 4 Unleashed

TextBox 公开了简单的整数属性,例如 CaretIndex、SelectionStart 和 SelectionEnd,而 RichTextBox 公开了 TextPointer 类型的 CaretPosition 属性和 TextSelection 类型的 Selection 属性。此外,RichTextBox 的内容存储在 FlowDocument 类型的 Document 属性中,而不是简单的字符串 Text 属性中。内容甚至可以包含嵌入式 UIElement,如果 RichTextBox 的 IsDocumentEnabled 属性设置为 true,它们可以是交互式的并引发事件。

事件开始起作用,必须添加BlockUIContainer,并将IsDocumentEnabled 属性设置为true(在RichTextBox),否则,事件将完全不起作用。

一般来说,我不明白你为什么需要它 TextBlockRichTextBox 中。使用它作为标准功能,它们几乎涵盖了RunParagraph 等。如果它们不匹配,则没有理由使用RichTextBox

请参阅有关 RichTextBox here 的精彩教程。

【讨论】:

  • 谢谢,但我忘了提到 Run 的类似代码可以正常工作(我刚刚编辑了问题)。为什么 TextBlock 不能正常工作?
  • @Jerry:我认为答案在引用中:custom event handlers that listen for MouseUp or MouseDown events from a RichTextBox。显然,这适用于RichTextBox 中的内容。我已经为TextBlock 尝试了各种鼠标事件,但没有成功。
  • 是的,但它也适用于在富文本框中运行。你试过吗?他们的待遇不同吗?
  • 抱歉,经过深入研究,这并不是我所需要的。我拥有的文本块需要在代码中设置,而不是在 xaml 中,并且是段落的一部分,所以我不想把它们都放在一个段落中。
  • 请给我详细信息好吗?我是 wpf 的新手。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-24
  • 1970-01-01
  • 1970-01-01
  • 2011-03-29
相关资源
最近更新 更多