How to Set inline Images Vertically Center in RichTextBox - wpf

I am working on WPF, i am display RichText data in RichTextBox for that have taken WindowsFormHost, inside that i am taking WinForm RichTextBox to display RichTextData which have Images + Text.
But while display that RichTextData images are align to Top and text are align to Bottom,
See in Image below, red circle is RichTextImage
i want to display images and Text in center. Like Below Image, the Red Circle is RichTextImage that is coming in center with text.
My XAML Code is:
<Window x:Class="WPFRichTextBox.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
Title="MainWindow" Height="600" Width="800" Background="LightBlue" xmlns:my="clr-namespace:WPFRichTextBox">
<Grid Loaded="Grid_Loaded">
<WindowsFormsHost Margin="0,424,0,22">
<wf:RichTextBox Text="RichTextBox" x:Name="richTbTest1" BorderStyle="None" Enabled="True" ForeColor="Black" Width="550" Multiline="True" />
</WindowsFormsHost>
</Grid>
</Window>
I have used WPF RichTextBox also, but in that also i am not able to Align text+Images in Center
<RichTextBox VerticalContentAlignment="Stretch" Height="158" HorizontalAlignment="Left" Margin="10,247,0,0" Name="richTextBox1" VerticalAlignment="Top" Width="754" />

You can use BaselineAlignment on a Run to center align the text. Here is an example:
<RichTextBox>
<FlowDocument>
<Paragraph>
<Run Text="Some text" BaselineAlignment="Center"/>
<Image Height="100" Width="100" Source="Images\Desert.jpg"/>
<Run Text="Some more text" BaselineAlignment="Center"/>
</Paragraph>
<Paragraph/>
<Paragraph>
<Run Text="Paragraph 2" BaselineAlignment="Center"/>
<Image Height="100" Width="100" Source="Images\Desert.jpg"/>
<Run Text="More text" BaselineAlignment="Center"/>
</Paragraph>
</FlowDocument>
</RichTextBox>
EDIT:
To apply the formatting to the entire RichTextBox try calling this method after the RichTextBox is populated:
public void CenterText()
{
var text = new TextRange(rtb.Document.ContentStart, rtb.Document.ContentEnd);
text.ApplyPropertyValue(Inline.BaselineAlignmentProperty, BaselineAlignment.Center);
}

I was able to get this working with a Span with the BaseAlignment attribute set to "Center".
<RichTextBox>
<FlowDocument>
<Paragraph>
<Span BaseAlignment="Center">
Center My Image
<Image ... />
</Span>
</Paragraph>
</FlowDocument>
</RichTextBox>

Related

WPF : ListBox.ItemTemplate doesn't react when click on text or image wpf xaml

I'm new to Xaml and WPF . I'm using the following code to extract botton title and image from RSS feeds .
The problem that the botton react only when user click on the border ... it dosen't react when user click on text or image .
<ListBox.ItemTemplate >
<DataTemplate >
<Button Background="{Binding C:AccentColors}" Width="400" Height="100" HorizontalAlignment="Left" >
<Grid Width="400" Height="100" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<Image Source="{Binding XPath=enclosure/#url}" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Top" />
<TextBlock TextWrapping="Wrap" Text="{Binding XPath=title}" FontWeight="Bold" Grid.Column="2"/>
</Grid>
</Button>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
You have to add the Click event in your button.
<Button Background="{Binding C:AccentColors}" Width="400" Height="100" HorizontalAlignment="Left" Click="MethodNameHere".....
and also you have to create and implement the method in the Window C# file
The common mistake is that somebody placed TextBlock on top of button without realizig it, because TextBlock has transparent Background.
Visually, the Text of TextBlock may be outside Button, but since TextBlock alignment is set to strech by default, it fills entire area.
hard to say if this is your case...
<Grid>
<Button Content="I'm not working" Margin="0,100,0,0" />
<TextBlock Text="I'm in top left corner" />
<Grid />
if you set TextBlock.Background to Red, you entire grid would be red.
The button is taking the clicks. You need a handler, either a command binding or if you're not using MVVM - a code behind method:
<Button Click="ButtonBase_OnClick"
Handler will look like this:
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
}

Scrolling a FlowDocument inside a TabControl

I have this XAML fragment:
<!-- ... -->
<TabControl>
<TabItem>
<!-- ... -->
</TabItem>
<TabItem Header="Source" ScrollViewer.HorizontalScrollBarVisibility="Visible" ScrollViewer.CanContentScroll="True">
<FlowDocumentScrollViewer>
<FlowDocument>
<Paragraph>
<TextBlock
Text="{Binding Path=CurrentObject.Source}"
FontFamily="Consolas,Courier,Segoe UI"
FontSize="12"
/>
</Paragraph>
</FlowDocument>
</FlowDocumentScrollViewer>
</TabItem>
</TabControl>
<!-- ... -->
The problem is that the flow document does not scroll horizontally. I've been unable to enable that.
Any clues?
Thanks in advance.
There are a couple things here. The first being that using a control in the Paragraph functions differently than a Run that would wrap to fit your FlowDocument.
The second is that the FlowDocument will fit your FlowDocumentScrollViewer. If you add a control to it like you did, it will fit the width of the FlowDocument and viewer and the text will go beyond the TextBlock borders. This means that your document doesn't need a scroll bar; your TextBlock would. You can see this by setting the TextWrapping property of the TextBlock to Wrap.
To get around this, set the PageWidth to something beyond the limits of the viewer width like so:
<FlowDocumentScrollViewer>
<FlowDocument PageHeight="1056"
PageWidth="816">
<Paragraph>
<TextBlock
Text="{Binding Path=CurrentObject.Source}"
FontFamily="Consolas,Courier,Segoe UI"
FontSize="12"
/>
</Paragraph>
</FlowDocument>
</FlowDocumentScrollViewer>
or bind to your TextBlock:
<FlowDocumentScrollViewer>
<FlowDocument PageHeight="1056"
PageWidth="{Binding ElementName=Part, Path=ActualWidth}">
<Paragraph>
<TextBlock
Text="{Binding Path=CurrentObject.Source}"
FontFamily="Consolas,Courier,Segoe UI"
FontSize="12"
/>
</Paragraph>
</FlowDocument>
</FlowDocumentScrollViewer>
The last thing is that the FlowDocumentScrollViewer has it's own HorizontalScrollBarVisibility property that you can use for this (unless some styling issue prevents it).

How to align the bottom edge of multiple TextBlocks with different FontSize

Here is the XAML sample:
<StackPanel Orientation="Horizontal" >
<TextBlock VerticalAlignment="Bottom" Text="Text1" FontSize="20" />
<Image VerticalAlignment="Bottom" ... />
<TextBlock VerticalAlignment="Bottom" Text="Text2" />
</StackPanel>
The result is that the textblocks have different bottom-margins depending on their FontSizes, but I need them all to be on one bottom line with no margins. How to get it? In my case I cant use TextBlock + Runs.
Forget several blobks : the bottom position dépends of the font size.
But, in a single paragraph, write the flow of your objects
You should use something like this :
<RichTextBlock>
<Paragraph>
<Span FontSize="148">Hello</Span>
<InlineUIContainer>
<Image Source="Assets/Logo.png"></Image>
</InlineUIContainer>
<Span FontSize="36">again</Span>
</Paragraph>
</RichTextBlock>

WPF textblock cuts off multiple lines on windows 7

I am using a textblock to display the product description under the product's image. The text must be fixed 100px wide but the height can grow up to 30px tall. If the text still can't fit, it must display ellipsis. Here is my xaml:
<StackPanel>
<!-- I use canvas here to reserve some space for animation (grow/shrink) -->
<Canvas Height="75" Width="75">
<Image x:Name="picture" Height="64" Width="64" .../>
<Canvas/>
<TextBlock Width="100" MaxHeight="30"
TextTrimming="CharacterEllipsis" TextWrapping="Wrap"
Text="{Binding Path=ProductDescription}"
HorizontalAlignment="Center" VerticalAlignment="Top" TextAlignment="Center">
</StackPanel>
The description can have multiple lines. For eg, "Wireless Mouse\nQuantity:20". It looks ok on XP but on Windows 7 only the first line shows up and there's no ellipsis. Can anyone spot the problem in my xaml?
There are several errors in your example: should , ".../>" isn't valid XAML and your TextBlock doesn't have a closing tag.
The follow XAML worked fine on for me on Windows 7:
<StackPanel>
<!-- I use canvas here to reserve some space for animation (grow/shrink) -->
<Canvas Height="75" Width="75">
<Image x:Name="picture" Height="64" Width="64" />
</Canvas>
<TextBlock Width="100" MaxHeight="30"
TextTrimming="CharacterEllipsis" TextWrapping="Wrap"
Text="I use canvas here to reserve some space for animation (grow/shrink)"
HorizontalAlignment="Center"
VerticalAlignment="Top"
TextAlignment="Center" />
</StackPanel>
Depending on the font size MaxHeight of 30 is almost just one line of text, so the textblock can't grow in height. Change it or remove it completely.

TextBlock text wrapping pushes other components

I have a TextBlock and a couple Buttons in a StatusBar. The Buttons are effectively right-aligned (e: actually the StatusBarItem containing them is). When the window is shrunk horizontally, and the text wraps, the TextBlock pushes the Buttons off the window to varying degrees.
Why does this happen, and how can I fix the positions of the Buttons?
<Window x:Class="TextWrapping.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<DockPanel>
<StatusBar DockPanel.Dock="Bottom">
<StatusBarItem>
<TextBlock Name="statusText" TextWrapping="Wrap" Text="when this text wraps, it pushes the buttons off the window" />
</StatusBarItem>
<StatusBarItem HorizontalAlignment="Right">
<StackPanel Orientation="Horizontal">
<Button>one</Button>
<Button>two</Button>
</StackPanel>
</StatusBarItem>
</StatusBar>
<TextBlock Text="shink this window horizontally" />
</DockPanel>
</Window>
You can see this blog post for more information, but basically the StatusBar is using a DockPanel to present it's items. So for the code you have above, the statusText is being docked left, and the buttons are filling the remaining space (but aligned horizontally within that area).
So as you size smaller, the TextBlock will always take as much space as it needs (allowing the buttons to size to zero). When the text is wrappped, the buttons get back a little more space as the TextBlock doesn't need all the horizontal space.
To fix it you can change your code to:
<DockPanel>
<StatusBar DockPanel.Dock="Bottom">
<StatusBarItem DockPanel.Dock="Right">
<StackPanel Orientation="Horizontal">
<Button>one</Button>
<Button>two</Button>
</StackPanel>
</StatusBarItem>
<StatusBarItem>
<TextBlock Name="statusText" TextWrapping="Wrap" Text="when this text wraps, it pushes the buttons off the window" />
</StatusBarItem>
</StatusBar>
<TextBlock Text="shink this window horizontally" />
</DockPanel>
Or you can use the trick shown the blog post, to replace the DockPanel with a Grid.

Resources