WPF ScrollView and TextBlock - c#

What am I doing wrong?
The following code works:
<ScrollViewer x:Name="scrollChatMessages">
<TextBlock x:Name="txtChatMessages" TextWrapping="Wrap"/>
</ScrollViewer>
But once I touch it up with the designer so it looks neater and doesn't take over the entire Grid, the ScrollView doesn't scroll the content of the Scrollblock anymore:
<ScrollViewer x:Name="scrollChatMessages" HorizontalAlignment="Left" Height="181" Margin="95,10,0,0" VerticalAlignment="Top" Width="300">
<TextBlock x:Name="txtChatMessages" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" Height="181" Width="300"/>
</ScrollViewer>
Could someone explain this behaviour to me?
Thanks in advance!

Without a good Minimal, Complete, and Verifiable code example it's impossible to say for sure. But you can see that the Designer has added a bunch of new property values for both elements. In particular, the ScrollViewer and TextBlock have been set to have the same exact width and height.
Naturally, with the contained element having exactly the correct dimensions to fit within the ScrollViewer, there's no need to scroll to see all of it. You need to remove the Width and Height property values from the TextBlock.

I solved it by placing it inside of a Grid.
<Grid x:Name="gridChatMessages" HorizontalAlignment="Left" Height="181" Margin="95,10,0,0" VerticalAlignment="Top" Width="300">
<ScrollViewer x:Name="scrollChatMessages">
<TextBlock x:Name="txtChatMessages" TextWrapping="Wrap"/>
</ScrollViewer>
</Grid>

Related

How to Fill SolidColorBrush/Ellipse [duplicate]

I am trying to create this in WPF (I realize I could just use an image, but I am trying to learn WPF):
(source)
This is what I have so far but it isn't producing the desired result, in that, the textbox seems completely hide the ellipse whereas it should simply have a transparent background:
<StackPanel>
<TextBlock HorizontalAlignment="Left" Margin="144,207,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top"/>
<Ellipse HorizontalAlignment="Left" Height="52" Margin="142,189,0,0" Stroke="Black" VerticalAlignment="Top" Width="52"/>
</StackPanel>
You can put things like this in a viewbox to make scaling easier, something like this. You'll need to remove the stack panel, it's going to stack items one on top of the other which isn't what you're after here. I used a grid in this case.
<Viewbox Width="100" Height="100">
<Grid Width="20" Height="20">
<Ellipse Stroke="Black"/>
<TextBlock HorizontalAlignment="Center" Text="i" TextAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</Viewbox>
Or you can use the unicode character: ⓘ
code 0x24D8
<TextBlock Text="ⓘ" FontSize="52" />
So a stackpanel will place the first item at the top, the second just below it, third below the second, and so forth. What you could do is use a Canvas or a Grid. Like the stackpanel, they are "Content Controls" and support placing multiple objects inside of them like you have done with the stackpanel.
So a really quick way to do what you're trying to accomplish would be:
<Grid >
<Ellipse HorizontalAlignment="Left" Height="52" Stroke="Black" VerticalAlignment="Top" Width="52"/>
<TextBlock Text="i" FontSize="52" Margin="18,-13,-6,13" />
</Grid>
You can do it using a border and a TextBlock. A square border will become a circle if you make its CornerRadius equals half its Width (or Height):
<Border Width="100" Height="100" CornerRadius="50" BorderBrush="Black" BorderThickness="2">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center"
FontSize="50" Foreground="Blue" >i</TextBlock>
</Border>
Don't use a StackPanel for this, the purpose of it is to stack things, not show them overlapped, you're using the wrong tool for that. Use a Grid, it's far more suited for what you're trying to do.
To have a transparent background, you have to either set the TextBlock's Background property to Transparent, or set a null background.
Background={x:Null}

Adding border to entire grid when I'm trying to add it to only a TextBlockC#

I'm trying to add a border to only a TextBlock but instead it is creating it around the entire grid. Here is the code :
<Border BorderBrush="Black" BorderThickness="6">
<TextBlock x:Name="txtInputUsername" HorizontalAlignment="Left" Margin="65,54,0,0" TextWrapping="Wrap" Text="Username" VerticalAlignment="Top" TextAlignment="Center" FontFamily="Open Sans" FontSize="20" Background="#FFF3F3F3" OpacityMask="Black"/>
</Border>
This is happening because child elements of a Grid will assume the Height and Width of the Grid (or the Grid cell) they are placed in, unless otherwise specified. The Border just looks like it is wrapping around the grid, because it is using it to infer its size.
There are a few ways to fix this, with the easiest being to specify the HorizontalAlignment and VerticalAlignment of the Border to Center. This causes the Border to snap around the bounds of the TextBlock instead of inferring its size.
In your case, it still produces some odd results because of your use of Margin to position the label. The Margin is still counted as being part of the control, so anything the wraps around the control will have to be larger to accommodate it. You should avoid that if at all possible, but if you really want to do it that way, more the Margin to the Border.
<Grid>
<Border
Margin="65,54,0,0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
BorderBrush="Black"
BorderThickness="6">
<TextBlock
x:Name="txtInputUsername"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Background="#FFF3F3F3"
FontFamily="Open Sans"
FontSize="20"
OpacityMask="Black"
Text="Username"
TextAlignment="Center"
TextWrapping="Wrap" />
</Border>
</Grid>
A better way to handle this though, is to learn about the different layout containers, and how to use them to position your controls, instead of Margin. These can be nested within each other to create almost any layout you can imagine, in a fairly nice, clean way.

ScrollViewer not showing C#

I am new to C# and not fully understand ScrollViewer. Please see the code below and tell me why no Scroll bar becomes visible when below mentiond groupbox gets displayed on screen.
Any help would be highly appreciated.
<ScrollViewer ScrollViewer.VerticalScrollBarVisibility="Auto" Grid.Row="5">
<GroupBox Name="grpDetail" Margin="5" Height="Auto" Grid.Row="5" ScrollViewer.VerticalScrollBarVisibility="Visible">
<my2:ucDisbursmentDetail Grid.Row="5" x:Name="ucDisbursmentDetail" Visibility="Collapsed"></my2:ucDisbursmentDetail>
</GroupBox>
</ScrollViewer>
Your ScrollViewer is simply bigger than it's content therefore it doesn't need to show the scrollbar. Just add some height to it
<ScrollViewer Height="300">
...
</ScrollViewer>

ScrollBar Disabled

I was trying to implement a ScrollViewer like so;
<Height="auto" Width="auto"
MaxHeight="500" MaxWidth="400"
ResizeMode="NoResize" WindowStyle="None">
<Grid>
<StackPanel>
<ScrollViewer Name="scrlBr">
<StackPanel Orientation="Vertical">
<TextBlock Name ="txtBlock" Margin="10" Height="auto"
Width="auto" TextWrapping="Wrap"></TextBlock>
<Button Name="btnOk" Click="btnOk_Click" Width="80"
HorizontalAlignment="Center">Close!</Button>
</StackPanel>
</ScrollViewer>
<Label HorizontalAlignment="Center" FontSize="3"
Name="lblScrollDown">\/</Label>
</StackPanel>
</Grid>
</Window>
The problem I'm having is that the scroll bar appears disabled, while the text obviously goes down off the window and I can't see the btnOk. Surely if the window has a fixed height and the TextBlock and Button, which are contained in the Scrollviewer, are bigger than the window then the ScrollBar should be enabled, no?
UPDATE
I worked out that the problem lies in having the ScrollViewer within a StackPanel. Might try it with a Grid instead... Update to come.
SOLUTION
I was right about the Stackpanel being the problem and went with Heinzi's suggestion of using the DockPanel and all's workin' fine. :) Thanks!
The problem is your StackPanel. It always takes all the vertical space it needs, so the container of the ScrollPanel is much larger than the window itself, and the ScrollViewer sees no need to scroll.
Solution: Replace the StackPanel with a DockPanel. Move the <Label> declaration to the top and dock it to the bottom of the DockPanel. The last child in a DockPanel (which is the ScrollViewer in this case) always fills the remaining space:
<Grid>
<DockPanel>
<Label DockPanel.Dock="Bottom" ... Name="lblScrollDown">\/</Label>
<ScrollViewer Name="scrlBr">
...
</ScrollViewer>
</DockPanel>
</Grid>
Try setting the CanContentScroll property on True from the ScrollViewer and set a fixed height of the StackPanel, as a StackPanel is designed to grow indefinitely in one direction. Or better, use a different panel to stack your items in.
Maybe you need write something like this
<ScrollViewer Name="scrlBr" VerticalScrollBarVisibility="auto" HorizontalScrollBarVisibility="auto">
...
</ScrollViewer>

Button Content Margin

I can't work out how to get rid of the margin around a button's content. Here is some example XAML:
<Button Background="Red" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
<Grid Background="Blue" Margin="0">
<TextBlock Text="me" Padding="0"></TextBlock>
</Grid>
</Button>
I can't seem to get rid of the red bit. Has anyone got any ideas?
You need to change the control template for the button. You can have alook at the following links
http://mark-dot-net.blogspot.com/2007/07/creating-custom-wpf-button-template-in.html
http://msdn.microsoft.com/en-us/magazine/cc163497.aspx

Categories