Remove WPF FlowDocument left padding? - c#

I'm attempting to align a flow document to the left with no padding, so that it matches exactly what you see in a TextBlock. I've recreated a simple example of what I'm basically trying to achieve. Here's what I have so far:
<Grid>
<TextBlock Foreground="Red" Height="Auto" TextWrapping="Wrap"
Margin="0" Padding="0" FontSize="50" FontFamily="Arial"
Text="Some text."/>
<RichTextBox BorderThickness="0" Background="Transparent" BorderBrush="Transparent" IsInactiveSelectionHighlightEnabled="False" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Disabled"
Height="Auto"
Margin="0" Padding="0" FontSize="50" FontFamily="Arial" >
<FlowDocument PagePadding="0" LineStackingStrategy="BlockLineHeight">
<Paragraph Margin="0" Padding="0" TextIndent="0">Some text.</Paragraph>
</FlowDocument>
</RichTextBox>
</Grid>
Here's the result:
As you can see, the red is the TextBlock version and the black is the RichTextBox/FlowDocument version. The FlowDocument text is offset by about 5 pixels to the right. I've tried to remove all padding that I am aware of, but I still can't get rid of that offset. Any help is appreciated.
NOTE: This question is found as duplicate of WPF: How to make RichTextBox look like TextBlock?

This offset is related to the caret implementation in the RichTextBox control.
Look at .Net 4.8 source, in the RichTextBox.cs file:
// Allocates the initial render scope for this control.
internal override FrameworkElement CreateRenderScope()
{
FlowDocumentView renderScope = new FlowDocumentView();
renderScope.Document = this.Document;
// Set a margin so that the BiDi Or Italic caret has room to render at the edges of content.
// Otherwise, anti-aliasing or italic causes the caret to be partially clipped.
renderScope.Document.PagePadding = new Thickness(CaretElement.CaretPaddingWidth, 0, CaretElement.CaretPaddingWidth, 0);
// We want current style to ignore all properties from theme style for renderScope.
renderScope.OverridesDefaultStyle = true;
return renderScope;
}
And the CaretElement.CaretPaddingWidth definition in the CaretElement.cs file:
// Caret padding width to ensure the visible caret for Bidi and Italic.
// Control(TextBox/RichTextBox) must have the enough padding to display
// BiDi and Italic caret indicator.
internal const double CaretPaddingWidth = 5.0;
Therefore, the only option that you can check is set the RichTextBox margin to Margin="-5,0,0,0".

Related

C# WPF Images not displaying

In my code, I have 3 images that are empty and then I set the source in the code behind. The relative path I'm giving them is the right one but the images are not displaying anyway. I got no clue how to fix this.
Xaml
<Border BorderThickness="1" Margin="44,135,433,248" BorderBrush="#FF000000">
<Image x:Name="imageHelmet" HorizontalAlignment="Left" Height="116" Margin="-1" VerticalAlignment="Top" Width="127" MouseEnter="helmet_MouseEnter"/>
</Border>
Behind
string source = #"..\..\..\Images\" + piece.Link;
BitmapImage bmp = new BitmapImage();
bmp.BeginInit();
bmp.UriSource = new Uri(source, UriKind.Relative);
bmp.EndInit();
imageChestplate.Source = bmp;
This is just one of them, but the rest are the same.
The image is likely hidden due to the margin of the border, at least that's what I saw when I attempted to recreate your problem.
Here, the Margin Property of the Border is set to 44,135,433,248. This means that there is a margin of 433 on the right side, and 248 on the bottom.
<Border BorderThickness="1" Margin="44,135,433,248" BorderBrush="#FF000000">
The edge of the window counts as something getting within the margin, so if the window is too small, it will not leave enough space for the margin, and as such the margin will be pushed over the image, hiding it.
To remedy this situation, change the right and bottom values in the margin to 0, and set the Border's HorizontalAlignment to Left, and VerticalAlignment to Top.
<Border BorderThickness="1" Margin="44,135,0,0" BorderBrush="#FF000000" HorizontalAlignment="Left" VerticalAlignment="Top">
<Image x:Name="imageHelmet" HorizontalAlignment="Left" Height="116" Margin="-1" VerticalAlignment="Top" Width="127" MouseEnter="helmet_MouseEnter"/>
</Border>
This way, there's no margin on the right and bottom sides to get pushed over the image, and the alignment makes it so the left and top alignments are used correctly.

Changing size of the frame and elements in UWP

I want to know if there is a way to resize the frame and the elements inside of it when the window size change. I always want to have the same proportion in the size of the elements inside the frame.
Example:
1- Windowsize = 100(in x) and Imagesize = 50(in x) locationx = 25
2- Windowsize = 50(in x) and Imagesize = 25(in x) location x = 12.5(~12)
In this case, the windowsize is "something", imagesize is 1/2 of "something" and locationx of the image is 1/4 of something. I wan't to do something like this but with every element inside the frame.
Thanks!
You can use the <ViewBox/> control which does exactly that.
<Page>...
<Grid>
<ViewBox HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<StackPanel>
<Button Content="test" HorizontalAlignment="Left"/>
<TextBlock Text="some text"/>
</StackPanel>
</ViewBox>
</Grid>
</Page>
In the example below, the ViewBox is placed inside a Grid and stretched both Horizontally and Vertically which causes it to stretch with the Page resize.
Reference docs here.

XAML Image gets distorted after compilation

Have a checkbox with custom control template which looks like this in design view:
XAML code:
<CheckBox IsChecked="{Binding Fareklasse21}" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Row="1" Grid.Column="1">
<CheckBox.Template>
<ControlTemplate>
<StackPanel Orientation="Vertical" VerticalAlignment="Center">
<Image Source="pack://application:,,,/Asd.WWs.Client.Wpf;component/Resources/ADR-M.png" Width="64" Height="64" SnapsToDevicePixels="True">
</Image>
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type CheckBox}}}"></CheckBox>
<TextBlock>2.1</TextBlock>
</StackPanel>
</StackPanel>
</ControlTemplate>
</CheckBox.Template>
When I start the application, the image (which is originally 64x64px) gets distorted (and enlarged?)
Could it be that the image inherits some value from the Prism wrapper? I can't really see anything interesting while doing live inspection:
Here are the properties of the specific image:
The WPF graphics system uses device-independent units to enable resolution and device independence. Each device independent pixel automatically scales with the system's dots per inch (dpi) setting. This provides WPF applications proper scaling for different dpi settings and makes the application automatically dpi-aware. See also wiki page.
This is the reason why if you even specify Stretch=None for an Image control, you may notice that the image does not appear at the expected number of pixels wide/high. This can happen if the image’s resolution (DPI) doesn’t match your current system DPI.
The conversion from physical pixels to DIPs uses the following formula.
DIPs = pixels / (SystemDPI / 96.0)
If you want to convert DIP to the "real" pixels you can use next formula:
Width (pixels) = Width (WPF Units) * (SystemDPI / 96)
Height (pixels) = Height (WPF Units) * (SystemDPI / 96)
You can specify element size in DIP, inches, centimeters or points. But it's better to use vectorized graphics if possible.
If you have SVG files you can use sharpvector framework via nuget:
Install-Package SharpVectors
So there is SvgViewbox to render SVG in XAML:
<UserControl ...
xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
...>
...
<svgc:SvgViewbox Margin="5" Height="20" Width="20" Stretch="Uniform" Source="/Resources/Icons/Sample.svg"/>
...
</UserControl>

WP 8.1 text scaling

So say I have a textblock with a fontsize 32. The value of the text property is a variable amount of characters. If the text at a fontsize of 32 is cut off, how could i down scale the fontsize until the total width of the textblock is equal to the page width?
-I'd post a screenshot but not enough rep :/
The best solution is insert the TextBlock inside a fix width ViewBox:
<Viewbox Width="300" StretchDirection="Both" >
<TextBlock x:Name="testblock" Foreground="Magenta" FontSize="24" Text="This is a test"/>
</Viewbox>
And that will make the job without any effort. Change the parameters depending you need, and you can insert the textblock inside a border,etc.

How do I get a ScrollViewer with a Rectangle inside to stop scrolling when it reaches the end of the rectangle?

I have created a Rectangle inside of a ScrollViewer like this
<ScrollViewer ManipulationMode="Control" x:Name="songScrollViewer" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Disabled" Height="270" VerticalAlignment="Center" Width="728" Canvas.Top="20" d:LayoutOverrides="HorizontalMargin" >
<Rectangle x:Name="musicBG" Fill="#FF0692FD"/>
</ScrollViewer>
During the use of the app, the size of MusicBg changes, sometimes to something around 3,000 pixels width.
musicBG.Width = _songLength*PixelsPerSecond
However, while scrolling the scrollViewer, it allows me to scroll the rectangle all the way off the screen.
For example this line of code gives me the following values when I have moved the rectangle as far as I want to move it.
if (songScrollViewer.HorizontalOffset > songScrollViewer.ScrollableWidth)
HorizontalOffset has a value of ~1200 and ScrollableWidth has a value of about ~2900.
How can I get this to be done properly so that the rectangle is not scrolled completely off the screen?
I would expect a HorizontalOffset of about 1200 to only push the rectangle about halfway through to it's destination, and not make it start going off screen.
ANSWER:
After much frustration, I was able to solve this problem by using Canvas instead of Border or Rectangle.
I'll award points if anyone can explain why this problem happened, and if there is a less processor intensive control that would work better than canvas.
Edit: Screen shots:
Bad Code:
<ScrollViewer ManipulationMode="Control" x:Name="songScrollViewer" Width="720" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Disabled" Height="270" VerticalAlignment="Top" Canvas.Top="20" HorizontalAlignment="Left" >
<Border x:Name="musicBG" Background="#FF0692FD" VerticalAlignment="Top" HorizontalAlignment="Left" Height="270" />
</ScrollViewer>
Image of bad scroll with bad code:
Good working code:
<ScrollViewer ManipulationMode="Control" x:Name="songScrollViewer" Width="720" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Disabled" Height="270" VerticalAlignment="Top" Canvas.Top="20" HorizontalAlignment="Left" >
<Canvas x:Name="musicBG" Background ="#FF0692FD" Height="270" >
<Border Background="#FF0692FD" VerticalAlignment="Top" HorizontalAlignment="Left" Height="270" />
</Canvas>
</ScrollViewer>
Good Scroll: Notice it says 170 seconds on the bottom right instead of the smaller number of 118 seconds in the bad scroll.
I believe your right, wp7 won't render shapes that are bigger then 2048 pixels. So the reason it's scrolling of the page is because it's treating it as if it were bigger then 2048 but you can only see up to a width of 2048px and its just scrolling over to the "ghost" part of the rectangle.
I'm not sure if you can override this but the best solution I could come up with (without overriding) is by splitting up your rectangle into chucks that are smaller then 2000 (just to be safe) and then displaying them seamlessly in a horizontal stack panel inside the scroll viewer. The problem with this is that depending on how you've coded it, this solution might be hard to implement; but you might just be able to split it in your ViewModel when displaying it and your logic would only see it as one big chunk.

Categories

Resources