嵌套的TextBlocks和Hyperlinks,你如何在C#中复制这个XAML?

时间:2022-06-17 02:46:23

I have this XAML:

我有这个XAML:

<TextBlock TextWrapping="Wrap" Foreground="Green"
           Text="This is some Green text up front. ">
    <TextBlock Foreground="Blue">
        This is some Blue text.
    </TextBlock>
    This is some Green text following the Blue text. 
    <Hyperlink>
        <TextBlock Text="And finally, this is a Hyperlink." TextWrapping="Wrap"/>
    </Hyperlink>
</TextBlock>  

And I'd like to know how to replicate it procedurally in C#.

我想知道如何在C#中以程序方式复制它。

I know how to create TextBlocks in C# with something like:

我知道如何在C#中创建TextBlocks,例如:

TextBlock tb = new TextBlock();
tb.Text="Some text"

And I can put multiple TextBlocks together in a panel within C#. But I don't see how you go about putting TextBlocks into other TextBlocks, and TextBlocks into Hyperlinks into TextBlocks.

我可以在C#中的一个面板中放置多个TextBlock。但我不知道如何将TextBlocks放入其他TextBlocks,而将TextBlocks放入超链接到TextBlocks。

Are some container objects and extra TextBlock objects being created automatically, somehow? Or does the TextBlock have some methods/properties that allow it to contain the other items?

是不是会自动创建一些容器对象和额外的TextBlock对象?或者TextBlock是否有一些方法/属性允许它包含其他项?

Other related questions:
1. What's the best way to add something like a Click() event to the Hyperlink?
2. Is there a way to get the blue text to wrap more cleanly? In the above XAML, as soon as the rightmost word would need to wrap, the entire block of blue text is wrapped instead.

其他相关问题:1。将什么是Click()事件添加到超链接的最佳方法是什么? 2.有没有办法让蓝色文字更干净地包裹?在上面的XAML中,只要最右边的单词需要换行,就会包裹整个蓝色文本块。

Thanks for any illumination you can provide.

感谢您提供的任何照明。

2 个解决方案

#1


7  

You can modify the collection of Inlines exposed via the TextBlock's Inlines property. The above XAML sample would look a little something like this:

您可以修改通过TextBlock的Inlines属性公开的Inlines集合。上面的XAML示例看起来像这样:

TextBlock tb = new TextBlock
               {
                  Text = "This is some Green text up front.",
                  Foreground = Brushes.Green
               };

InlineCollection tbInlines = tb.Inlines;

tbInlines.Add(new Run
              {
                 Text = "This is some Blue text.",
                 TextWrapping = TextWrapping.Wrap,
                 Foreground = Brushes.Blue
              });

tbInlines.Add(new Run
              {
                 Text = "This is some Green text following the Blue text."
              });

Run hyperlinkRun = new Run("And finally, this is a Hyperlink.");

tbInlines.Add(new Hyperlink(hyperlinkRun));

As for your related questions:

至于你的相关问题:

1A) While it's possible to hook an event handler to every single Hyperlink instance using the RequestNavigate event on the class, that can be costly to setup and use more memory than is necessary. Instead I recommend leveraging routed events and simply hooking the RequestNavigate event at the container where all of your hyperlinks will be. You can do this like so:

1A)虽然可以使用类上的RequestNavigate事件将事件处理程序挂钩到每个单独的Hyperlink实例,但设置和使用的内存可能比必要的成本高。相反,我建议利用路由事件,只需在所有超链接所在的容器上挂钩RequestNavigate事件。你可以这样做:

myContainer.AddHandler(
                     Hyperlink.RequestNavigateEvent, 
                     new RequestNavigateEventHandler(
                                                      (sender, args) =>
                                                      {
                                                        /* sender is the instance of the Hyperlink that was clicked here */
                                                      }));

2A) In your XAML example it's treating the inner TextBlock as an element that needs to be wrapped all together. If you're using my Run based approach the wrapping should be inherited from the containing text block.

2A)在你的XAML示例中,它将内部TextBlock视为需要一起包装的元素。如果您使用的是基于Run的方法,则应该从包含的文本块继承包装。

#2


1  

I don't know about TextBlocks, but here is how you would do it in a RichTextBox. You could use a RichTextBox instead of a TextBlock.

我不知道TextBlocks,但这里是你如何在RichTextBox中做到这一点。您可以使用RichTextBox而不是TextBlock。

 RichTextBox rtbTest = new RichTextBox();
 rtbTest.IsDocumentEnabled = true;

 FlowDocument fd = new FlowDocument();
 Paragraph para = new Paragraph();

 Run r4 = new Run("Some Text To Show As Hyperlink");
 Hyperlink h4 = new Hyperlink(r4);
 h4.Foreground = Brushes.Red; //whatever color you want the HyperLink to be

 // If you want the Hyperlink clickable
 h4.NavigateUri = new Uri("Some URL");
 h4.RequestNavigate += new RequestNavigateEventHandler(h_RequestNavigate);
 // Leaving the two previous lines out will still make the Hyperlink, but it won't be clickable

 // use this if you don't want an underline under the HyperLink
 h4.TextDecorations = null;

 para.Inlines.Add(h4);

 fd.Blocks.Add(para);

 rtbTest.Document = fd;

For normal text, I just used the HyperLink, but removed the two lines that made it clickable. This would give the text the color, but it wouldn't be clickable. Though it still makes the cursor change still. Though I am sure there is a property to change that also.

对于普通文本,我只使用了HyperLink,但删除了使其可点击的两行。这会给文本带来颜色,但不会被点击。虽然它仍然使光标变化。虽然我确信有一个属性可以改变它。

#1


7  

You can modify the collection of Inlines exposed via the TextBlock's Inlines property. The above XAML sample would look a little something like this:

您可以修改通过TextBlock的Inlines属性公开的Inlines集合。上面的XAML示例看起来像这样:

TextBlock tb = new TextBlock
               {
                  Text = "This is some Green text up front.",
                  Foreground = Brushes.Green
               };

InlineCollection tbInlines = tb.Inlines;

tbInlines.Add(new Run
              {
                 Text = "This is some Blue text.",
                 TextWrapping = TextWrapping.Wrap,
                 Foreground = Brushes.Blue
              });

tbInlines.Add(new Run
              {
                 Text = "This is some Green text following the Blue text."
              });

Run hyperlinkRun = new Run("And finally, this is a Hyperlink.");

tbInlines.Add(new Hyperlink(hyperlinkRun));

As for your related questions:

至于你的相关问题:

1A) While it's possible to hook an event handler to every single Hyperlink instance using the RequestNavigate event on the class, that can be costly to setup and use more memory than is necessary. Instead I recommend leveraging routed events and simply hooking the RequestNavigate event at the container where all of your hyperlinks will be. You can do this like so:

1A)虽然可以使用类上的RequestNavigate事件将事件处理程序挂钩到每个单独的Hyperlink实例,但设置和使用的内存可能比必要的成本高。相反,我建议利用路由事件,只需在所有超链接所在的容器上挂钩RequestNavigate事件。你可以这样做:

myContainer.AddHandler(
                     Hyperlink.RequestNavigateEvent, 
                     new RequestNavigateEventHandler(
                                                      (sender, args) =>
                                                      {
                                                        /* sender is the instance of the Hyperlink that was clicked here */
                                                      }));

2A) In your XAML example it's treating the inner TextBlock as an element that needs to be wrapped all together. If you're using my Run based approach the wrapping should be inherited from the containing text block.

2A)在你的XAML示例中,它将内部TextBlock视为需要一起包装的元素。如果您使用的是基于Run的方法,则应该从包含的文本块继承包装。

#2


1  

I don't know about TextBlocks, but here is how you would do it in a RichTextBox. You could use a RichTextBox instead of a TextBlock.

我不知道TextBlocks,但这里是你如何在RichTextBox中做到这一点。您可以使用RichTextBox而不是TextBlock。

 RichTextBox rtbTest = new RichTextBox();
 rtbTest.IsDocumentEnabled = true;

 FlowDocument fd = new FlowDocument();
 Paragraph para = new Paragraph();

 Run r4 = new Run("Some Text To Show As Hyperlink");
 Hyperlink h4 = new Hyperlink(r4);
 h4.Foreground = Brushes.Red; //whatever color you want the HyperLink to be

 // If you want the Hyperlink clickable
 h4.NavigateUri = new Uri("Some URL");
 h4.RequestNavigate += new RequestNavigateEventHandler(h_RequestNavigate);
 // Leaving the two previous lines out will still make the Hyperlink, but it won't be clickable

 // use this if you don't want an underline under the HyperLink
 h4.TextDecorations = null;

 para.Inlines.Add(h4);

 fd.Blocks.Add(para);

 rtbTest.Document = fd;

For normal text, I just used the HyperLink, but removed the two lines that made it clickable. This would give the text the color, but it wouldn't be clickable. Though it still makes the cursor change still. Though I am sure there is a property to change that also.

对于普通文本,我只使用了HyperLink,但删除了使其可点击的两行。这会给文本带来颜色,但不会被点击。虽然它仍然使光标变化。虽然我确信有一个属性可以改变它。