WPF : How to animate element width whenever it changes - wpf

This should be easy but I'm blanking out here.
I have a TextBlock inside of a Border control. The Width of the Border changes based on the length of the text in the TextBlock (updated in ViewModel). I would like this change in Width to be animated so that the width grows slowly (instead of jerky).
My Xaml:
<Border x:Name="myBorder" BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Left" VerticalAlignment="Top">
<TextBlock x:Name="myTextBlock" HorizontalAlignment="Left" Text="Some Text"/>
</Border>

This is a perfect job for Expression Blend. You will need to create a Storyboard animation. Then once its created go into the code behind in visual studios and play it. You can tell it to play to a certain point based on how much text you have in your text block.
Here is a basic tutorial
http://www.silverlightbuzz.com/2009/10/12/animating-with-storyboards-in-blend/
This example has back end code also
http://dotnet.dzone.com/articles/wpf-storyboard-%E2%80%93-what-it-and

Related

WPF Border partially not showing when I set a margin

I'm trying to make a WPF application and was trying to make a square border. I want it to be 10 pixels away from the top, bottom and right edges of the grid. I tried messing with the XAML code but that just produced all sorts of malformations, so I used Visual Studio's Properties tab instead. If I set the right and bottom border to 0 it looks fine, but it covers the edge like this. Code:
<Border BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Right" Height="180" Margin="604,10,0,0" VerticalAlignment="Bottom" Width="180"/>
If I however add a 10 border to right and bottom (which is what I've used in my previous WPF apps so far) this happens. Code:
<Border BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Right" Height="180" Margin="604,10,10,10" VerticalAlignment="Bottom" Width="180"/>
They both looks the same in the preview btw. Also sorry, I can't post direct images yet, since I don't have enough reputation.
The reason why the left border is not visible is because of the 604 as the left margin set that to 0 and you should be all good.
<Border BorderBrush="Black" BorderThickness="1" Height="180" Width="180" Margin="0,10,10,10" HorizontalAlignment="Right" VerticalAlignment="Bottom"/>
That being said, I do not recommend using fixed Height and Width in your XAML UI.
I've already got a few answers on this so feel free to check them out:
Adaptive UI with XAML
Checkout the Good practices section of this answer

How do I properly draw and scale a Canvas as a WPF background to a control?

I have a StackPanel that needs to contain drawn background. Specifically, my StackPanel needs to have the ability to grow and the rectangle must grow with the StackPanel, but must remain pseudo-anchored to each side at a fixed position.
I've attempted to use the Canvas.Left, Canvas.Right, Canvas.Top and Canvas.Bottom attached properties, but so far they've not worked. Furthermore, this does seem to work when drawing within Canvas objects, just not when they are embedded within a VisualBrush set as a background. How can I accomplish drawing this resizable, rectangular background within my StackPanel?
Below is the state of my current code. I've tried various approaches but none seem to work.
My Code:
<StackPanel DockPanel.Dock="Right" Orientation="Vertical" VerticalAlignment="Center">
<StackPanel.Background>
<VisualBrush Stretch="None">
<VisualBrush.Visual>
<Canvas Background="Magenta" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
Rectangle Fill="#FFDDECF7" Canvas.Left="20" Canvas.Top="20" Canvas.Bottom="20" Canvas.Right="0"/>
</Canvas>
</VisualBrush.Visual>
</VisualBrush>
</StackPanel.Background>
...
</StackPanel>
This currently doesn't render anything. I set the canvas background to magenta just so I could see if it were drawing, and I'm not even seeing that. Other attempts have drawn the canvase, however, the blue rectangle is always stretched to fill the window, regardless of attached canvas property settings.
Sample:
The image below is a sample of what I want. Again, I'm using an ugly Magenta color to show the offset of the internal, blue rectangle. As the StackPanel grows or shrinks, the rectangle needs to be affixed to the top, left, right and bottom.
My suggestion is to place the stackpanel inside a grid:
<Grid DockPanel.Dock="Right" VerticalAlignment="Center" Background="Magenta">
<Rectangle Margin="20" Fill="#FFDDECF7"/>
<StackPanel Orientation="Vertical">
no background...
</StackPanel>
</Grid>
Wrap Canvas into a ViewBox, then work on a ViewBox. As far as I know Canvas doesn't support scalling too well.

Text disappear while FlowDirection set to RightToLeft

Please check the code below. I am working with Silverlight.
<Canvas x:Name="LayoutRoot" Background="blue" Width="100" FlowDirection="RightToLeft">
<TextBlock x:Name="tb2" Text="abcd" Canvas.Top="100" Canvas.Left="20" Foreground="White"/>
</Canvas>
FlowDirection set to RightToLeft in canvas or TextBlock makes the text to disappear..Any idea what is causing this problem. and how to make it work?
From my short tests it seems FlowDirection is available on Canvas only because it's part of UIElement. But using it on a Canvas doesn't really make much sense. A canvas is just that - a canvas on which you can place objects in exact places.
FlowDirection works quite well when using inside a Grid. I don't know what you're trying to achieve, but I'd start with rewriting your control to use Grid rather than Canvas.

Why does WP7 ListPicker have different margins and height to TextBox

I have a page in my WP7 app consisting of a TextBox beside a ListPicker. In their default modes, they don't line up properly; the ListPicker has a different padding to the TextBox, and its height is also different.
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel Orientation="Horizontal">
<TextBox HorizontalAlignment="Left" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top"/>
<toolkit:ListPicker Width="170" ItemsSource="{Binding l}" Style="{StaticResource ListPickerStyle1}" VerticalAlignment="Top"/>
</StackPanel>
</Grid>
Manually tweaking the ListPicker's template to fit in correctly here is tricky and error prone. For example, when its height is adjusted, the caption (i.e. the text of the selected item) is no longer in the centre of the component.
My app is currently failing MS app review because the components are not all the same height.
Is there an easy way for me to set the toolkit:ListPicker to have the same appearance as a TextBox?
The simplest solution will be to take a copy of the the default style and tweak that using Blend to be exactly how you want it to look. This will take a little trial and error to sort out.
You can then use the implicit styling rules to apply it to all ListPickers without having to explicitly set the style on each instance:
<Style x:Key="MyListPickerStyle
TargetType="toolkit:ListPicker>
.... your tweaks here
</Style>
<Style TargetType="toolkit:ListPicker"
BasedOn="{StaticResource MyListPickerStyle}" />
It may be easier to tweak the TextBox Style of course :)

Unable to get vertical scroll bars in an WPF TextBlock

I'm presenting text in a wpf TextBlock control (.Net 3.5). The content of the textblock varies depending on what the user selects in a list box. The text wraps, so I don't need an horizontal scroll bar. However, there is often more text than the amount the window can display, so I need a vertical scroll bar.
As I started searching I quickly found that the answer is to wrap the TextBlock in a ScrollViewer. However, It Does Not Work (TM) and I'm hoping someone can help me work out why.
This is the structure of the UI code:
<Window x:Class=..>
<StackPanel>
<ListBox HorizontalAlignment="Stretch"
VerticalAlignment="Top" Height="200"
SelectionChanged="listbox_changed" SelectionMode="Single">
</ListBox>
<Button Click="Select_clicked">Select</Button>
<ScrollViewer VerticalScrollBarVisibility="Auto">
<TextBlock Name="textblock" TextWrapping="Wrap"/>
</ScrollViewer>
</StackPanel>
</Window>
When the user selects an item in the list box, some text associated with this item is presented in the TextBlock. I would have thought that the code as it stands should have been all that's required, but it never provides me with a scroll bar.
Searching and experimenting have given me two clues: the root of the problem might be related to me updating the content of the TextBlock dynamically, and that the TextBlock does not resize itself based on the new content. I found a posting that seemed relevant that said that by setting the Height of the TextBlock to its ActualHeight (after having changed its content), it would work. But it didn't (I can see no effect of this).
Second, if I set the height (during design time) of the ScrollViewer, then I do get a vertical scroll bar. For instance, if I set it to 300 in the xaml above, the result is almost good in that the window as first opened contains a TextBlock with a vertical scroll bar when (and only when) I need it. But if I make the window larger (resizing it with the mouse during runtime), the ScrollViewer does not exploit the new window size and instead keeps its height as per the xaml which of course won't do.
Hopefully, I've just overlooked something obvious..
Thanks!
Because your ScrollViewer is in a StackPanel it will be given as much vertical space as it needs to display it's content.
You would need to use a parent panel that restricts the vertical space, like DockPanel or Grid.
<DockPanel>
<ListBox DockPanel.Dock="Top" HorizontalAlignment="Stretch"
VerticalAlignment="Top" Height="200"
SelectionChanged="listbox_changed" SelectionMode="Single">
</ListBox>
<Button DockPanel.Dock="Top" Click="Select_clicked">Select</Button>
<ScrollViewer VerticalScrollBarVisibility="Auto">
<TextBlock Name="textblock" TextWrapping="Wrap"/>
</ScrollViewer>
</DockPanel>

Resources