Silverlight scrolling text & max width issue - silverlight

I am trying to scroll text across the screen which is working well.
Update: I'm still stuck with problem and can now demonstrate it on my live app:
Go to
http://www.pokerdiy.com/poker-blinds-timer.aspx
and leave it non-fullscreen.
Click on the "Timer" tab at the top.
Then click on "Start Tourney". At
the top, a scrolling message will
appear from the right. On my monitor
(22 inch) - this cuts off before it
has finished the sentence.
Then right-click to resize to full
screen, and restart the tourney and
then start it again to show the same
message. You will see that it now
works!
This is a big problem as I want to scroll LONG messages across the top... any ideas please?
Problem Summary:
I have a Textblock off the screen to the right which has no width set and is bound to a string value. I programatically start an animation which changes the From and To value on CompositeTransform.TranslateX to move the whole textblock across the screen to give the appearance of scrolling. The width of this textblock autoadjusts to the bound string value and I set this to be the Animation To value (negative) so it takes it off the screen to the left (see code below).
So this all works fantastically... BUT not with long messages. There seems to be a width limit on something that truncates my text. At some point it cuts it off with a width limit (the last character is rendered in half, so it is not a character limit). I set up a loop to create a large string and output the ActualWidth of the Textblock and it shows as 17000 (which is correct). The Width is fine too, and the actual Text property shows the complete string... but the UI truncates it at a certain point, which I can't figure out.
So - 1) Is this approach ok (is there an easier way?) and 2) What is causing the truncation?
Thanks!
Xaml:-
<Storyboard x:Name="StoryboardScrollText" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)">
<DoubleAnimation x:Name="StoryboardScrollTextAnimation" Storyboard.TargetName="txtSystemMessage" From="500" To="-740" Duration="0:0:30" />
</Storyboard>
<TextBlock x:Name="txtSystemMessage" TextWrapping="NoWrap" Text="{Binding TourneyMessage}" Foreground="White" FontSize="20" VerticalAlignment="Center" >
<TextBlock.RenderTransform>
<CompositeTransform TranslateX="0"/>
</TextBlock.RenderTransform>
</TextBlock>
Code:-
mainPage.StoryboardShowTourneyMessage.Begin();
//has to scroll the whole message off the screen (plus a bit extra as it starts off the screen)
//get the leftmost position of the logo so it starts just behind it
mainPage.StoryboardScrollTextAnimation.From = GetPositionX(mainPage.NavigationGridLogo);
mainPage.StoryboardScrollTextAnimation.To = mainPage.txtSystemMessage.ActualWidth * -1 - 50;
mainPage.StoryboardScrollText.Begin();
MessageBox.Show(mainPage.txtSystemMessage.ActualWidth.ToString() + " " + mainPage.txtSystemMessage.Width.ToString());

Part 1: If you intend to do pixel based
animation, use a canvas as the
parent object. Grid will work, but see the cause of your problem in part 2 (below)
Part 2: Basically the truncation of your
text is caused by the parent
container cropping the child. This
is happening based on width of the
parent and it ignores the offset of
your text.
Solution:
If you place the TextBlock as a child
of a canvas, instead of a grid (or even just the TextBlock within a canvas within your grid), it will render
full length as a canvas will never clip its children by default.
You may need to add a clip rectangle
to the canvas to hide any parts of
the text that extend where you do
not want to see it, but this will depend on what other components are onscreen to hide the overlap. If you do add a clip rectangle, make sure you animate the text position using Canvas.Left and not the TranslateX or you may get the original problem back again!

Related

[XAML-WP8.1]Grid View background image clip to bounds

I'm new on Windows development and more in Windows Phone Development.
I'm trying to create a grid view composed of three cell.
Each grid view are composed of one image (for the background) and a textblock.
My background image is a cloud image and I want the first image partialy hidden by the second one and the second one partially hidden by the third one.
I tried to play with the margin of the cell for the y part, that's works but my cloud image doesn't make the entire width of my cell. So I tried the "UnifirmToFill" option but my images are cropped...
On iOS development in this case we can use the magic property "ClipToBounds", everywhere I saw the answer "use the clip to bounds property" but apparently this property is a legend or Visual Studio lie me...
Do you have an idea to resolve my problem ?
Thank you in advance!
To resume:
If I use the "uniformToFill" stretch option, my image is zoomed. It is ok for me.
But there is a way to display the cropped part? I want my image zoomed and displayed out the cell view.
In XAML there are four possible Stretch options:
None
The image is shown in it's original size. If its larger than the parent element, it'll only show the top left portion of the image that fits inside. If the image is smaller than the parent element, then it's shown in it's entirety.
Fill
The image is resized to fill the parent element. If the aspect ratios are different, then the image will be stretched to fit the parent. This will distort the image.
Uniform
The image will be scaled up as large as it can be, while still being completely inside of the parent. Unlike Fill which will stretch the image to make it fit perfectly, Uniform will keep the aspect ratio of the image and stop scaling when it reaches the bounds of the parent.
UniformToFill
This is the bastard child of the previous two. It will scale the image, while keeping the aspect ratio, until it fills the parent element. This means that some parts of the image will be clipped if the aspect ratios are different.
For more information on the Stretch enumeration, hit it up on MSDN
UPDATE
If you want to show the image outside of the bounds of the parent you could do something like this:
<Grid Width="100" Height="50">
<Grid.Clip>
<RectangleGeometry Rect="0 0 100 50"/>
</Grid.Clip>
</Grid>
This was suggested here on SO

How do I get a scrollbar to appear with a ListView when the height is auto?

I'm working on a Windows Store App.
I have a ListView with a bunch of items in it. It is nested in some stack panels and grids, but they all essentially are auto sized. Essentially, the ListView is given most of the right half of the screen, regardless of what size it is.
If I give the ListView a hard-valued Height, a scrollbar will automatically appear with no extra work. Great. But I don't want to set a height... I want it to be all of the area available in its container. If I try to be clever and set it to 9999 or something then it will not scroll.
I've done a bunch of research, and similar questions like this say that the thing that holds the ListView cannot give it infinite size like a StackPanel would. What alternatives do I have? How can I put a ListView in something with arbitrary space and get a scroll bar to appear?
My only thought is that there must be some way to, in the container that holds the ListView, tell the ListView that it has all available area in such a way that it's height gets set that that value. Sort of like how to have to set ListViewItem's HorizontalContentAlignment property to 'Stretch' in order to get the items within a ListView to know what what available width they actually have.
The essential bits of my layout is this:
<!-- Nested in some other stuff simple Grids and StackPanels, none of which has hard heights set (all auto or *) -->
<!-- Even if I made this a Grid with one Row, setting definition to * or Auto doesn't help the issue - no scroll bar appears -->
<StackPanel>
<!-- Other stuff that has Visibility="Collapsed"... I have code so that only one item at a time within this container will ever be visible, and it gets all available space. -->
<ListView ItemsSource="{Binding SomeBigList}" ItemTemplate="{StaticResource MyDataTemplate}" />
<!-- Other stuff that has Visibility="Collapsed" -->
</StackPanel>
How can I get a scrollbar to appear in the ListView without setting a hard height anywhere? Thanks for you're help.
Don't use a <StackPanel>.
If you are in control over what gets drawn and only one item is ever visible at any one time, then use a non-infinite sized container like <Grid>. You can put each item in the same row, or use a separate row if only for ease of spotting what's what.
I ran into similar on the Windows Phone app. You need to remove the variables of the other containers by creating a test page and determining which panel is causing your ultimate problem.
Create new blank page with a Grid and ListView.
Work the grid sizing to be automatic (auto) or * sized until you see the horizontal scroll bar.
Once the horizontal scroll bar appears, add the other containers, one by one until the scroll bar disappears. That will inform you of the culprit which is causing the miss-sizing and ultimately the failure of the scrollbar to appear.

How can I prevent WPF from clipping my image?

I am writing a WPF app that displays an image that is initially centered. The user can zoom in/out and move the image, which are implemented using ScaleTransform and TranslateTransform. That works great.
The problem is when the image is significantly bigger than the window, and the user moves the image or zooms out enough so that the entire image should be visible. The portion of the image that was originally hidden isn't rendered, and instead only the originally viewable part of the image is drawn.
Based on some other questions, if I put my image inside of a Canvas that will cause the entire image to be rendered, and when moved it will be rendered correctly. The problem is that I don't want my image to be in a Canvas, since that prevents any other layout from occurring - the HorizontalAlignment and VerticalAlignment properties are ignored (so the image is no longer centered), and I need to implement an option that will draw the image as large as possible to fill the entire area of the window which no longer works (setting the Stretch property to UniformToFill doesn't do anything).
Currently the two transforms are set to the RenderTransform property. If I use LayoutTransform instead, the entire image is drawn, but this also prevents the user from moving any portion of the image off the edge of the window (which is behavior that I would like to keep).
How can I tell WPF to always render the entire image without using a Canvas or a LayoutTransform?
I suggest not using a TranslateTransform but instead rely on the ScrollViewer.
<ScrollViewer>
<Grid>
<Image Source="blabla">
<Image.LayoutTransform>
<ScaleTransform />
</Image.LayoutTransform>
</Image>
</Grid>
</ScrollViewer>
The ScrollViewer gives the Image infinite space to expand, the entire image will be rendered. The Grid forces a centered layout while still allowing the image to expand. If you don't like the scrollbars to control the translate then you can hide them and roll your own solution.
LayoutTransform is definetely the way to go, so that the image's actual size in pixels (based on the zoom) is properly reflected onto your window.

How can I create an opacity mask in wpf that doesn't scale?

Ok, I've created a PNG-24 with transparency. It's basically a grayscale image that uses 'colors' in between black and transparent instead of black and white. I did this so I can use this as the Opacity Mask of a colored rectangle, thus rendering the image in whatever color I want using only a single graphic.
However, for the life of me, I can't get WPF to stop anti-aliasing the da*n image!!
I've set 'SnapesToDevicePixels' on the rectangle to which the brush is applied... I've set the ImageBrush's Scale to 'None'... I've set its ViewPort and the ViewBox to absolute units and sized them exactly to the source image. But no matter what I try, WPF still insists on trying to smooth things out! This is VERY frustrating!!!
So... anyone know how to use an image as an opacity mask but not lose the pixel-precise drawing that we have done? I just want WPF to render the damn thing as we drew it, period!
I have tried to reproduce your problem. Simply like this:
<Rectangle Width="200" Height="200" Fill="Red">
<Rectangle.OpacityMask>
<ImageBrush ImageSource="/mask.png"/>
</Rectangle.OpacityMask>
</Rectangle>
mask.png contains a simple diagonal mask, like that half of rectange is visible and other half is 100% transparent.
And recrangle is rendering pixel perfect (and aliased, as you want).
I think, that you may a DPI setting, that is not native to your monitor, and WPF just can`t render images correctly.
GOT IT! It's a layout issue that for some reason, there's no easy way to change. However, there's a value you can set called UseLayoutRounding that fixes it. I just set it at the root level (for this fauxample, a grid...)
<Grid UseLayoutRounding="True">
....
</Grid>
...and BAM! Works like a charm! "Sort of" like a 'SnapsToDevicePixels' but for positioning of elements (i.e. it rounds all layout-related values like left, width, etc. whereas SnapsToDevicePixels snaps the layout to the on-screen pixels when rendering.)
M

Can I limit WPF TextBlock height to two lines?

I just received a requirement to display a length of text in a control. The control is of a particular width and will be up to 2 lines in height. If it renders longer than two lines it will just display "..." at the end of the string.
Is this possible with any of the stock standard WPF controls?
Thanks,
D.
Set the Height of the TextBlock to be high enough to fit two lines. Set the TextWrapping to Wrap and the TextTrimming to CharacterEllipsis or WordEllipsis.
For the default Segoe UI 12Pt font, I find this does it
<TextBlock TextWrapping="Wrap" Height="40" TextTrimming="CharacterEllipsis" />
You could probably do some code behind to work out the height it should be be for a particular font if you want.
That's not standard behavior that I've ever found, but again I've not looked for it.
One possibility is to use a monospace font in a TextArea control, and then if the string is greater than however many characters fit in the area, only display the right N characters with the ellipses

Resources