Clicking on a TextBlock in WPF richtextbox

故事扮演 提交于 2020-01-14 13:11:26

问题


I have a flowdocument like this:

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;

and I need an event to trigger on mouse click on a textblock:

    <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;
        }

The event handler for Run is called and works properly (Changing inline in flowdocument) , but that for TextBlock isn't.

What am I doing wrong? Thanks


回答1:


Quote from MSDN:

Important

RichTextBox has built-in handling for the bubbling MouseUp and MouseDown events. Consequently, custom event handlers that listen for MouseUp or MouseDown events from a RichTextBox will never be called. If you need to respond to these events, listen for the tunneling PreviewMouseUp and PreviewMouseDown events instead, or register the handlers with the HandledEventsToo argument (this latter option is only available through code). Do not mark the event handled unless you deliberately want to disable RichTextBox native handling of these events, and be aware that this has notable effects on the control's UI.

So you need to look for alternatives. I can suggest a few.

First, you can set an event handler PreviewMouseDown for all RichTextBox:

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

Second, use the BlockUIContainer and put the text in the content button. For example:

<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>

Third, you can set the event handler for the Paragraph like that:

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

para.MouseLeftButtonDown += new MouseButtonEventHandler(TextBlock_Click);

Edit

Quote from Adam Nathan's book WPF 4 Unleashed:

Whereas TextBox exposes simple integer properties such as CaretIndex, SelectionStart, and SelectionEnd, RichTextBox exposes a CaretPosition property of type TextPointer and a Selection property of type TextSelection. In addition, RichTextBox’s content is stored in a Document property of type FlowDocument rather than the simple string Text property. The content can even contain embedded UIElements, and they can be interactive and raise events if RichTextBox’s IsDocumentEnabled property is set to true.

Events began to work, it is necessary to add BlockUIContainer with IsDocumentEnabled property is set to true (in RichTextBox), otherwise, the event will not working altogether.

In general, I do not understand why you need it TextBlock inside RichTextBox. Use it the standard features, they pretty much cover, those Run, Paragraph, etc. If they do not match, then there is no reason to use RichTextBox.

See the nice tutorial about RichTextBox here.



来源:https://stackoverflow.com/questions/17908449/clicking-on-a-textblock-in-wpf-richtextbox

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!