Silverlight: Cannot manage to get ScrollViewer and WrapPanel to work together - silverlight

I'm using a WrapPanel to format some text. During runtime I add TextBlocks and StackPanels as Children. Obviously I need a scrollbar depending on the data size. Searching the web I found multiple answers which all propose to put a ScrollViewer around the WrapPanel. That makes sense to me, but I cannot get it to work. Here's my code:
scrollView = new ScrollViewer();
scrollView.HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled;
scrollView.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
scrollView.HorizontalAlignment = HorizontalAlignment.Stretch;
scrollView.VerticalAlignment = VerticalAlignment.Stretch;
scrollView.Margin = new Thickness(0);
scrollView.BorderThickness = new Thickness(0);
textPanel = new WrapPanel();
textPanel.Width = Width;
scrollView.Content = textPanel;
That does not work. The ScrollViewer seems to grow with the contained WrapPanel. If I set the vertical scroll bar to visible, I can see that the scrollbar grows with the content. But the ScrollViewer grows out of the containing window and therefor no scrollbar is displayed ever.
Any hint what I might be doing wrong?
cheers,
Achim

You need something to contrain the size of the WrapPanel and the ScrollViewer - you could set the width and height of the viewer then use an element binding on the wrappanel:
<ScrollViewer x:Name="ScrollViewer1"
Width="200"
Height="200"
ScrollViewer.VerticalScrollBarVisibility="Visible"
ScrollViewer.HorizontalScrollBarVisibility="Visible" >
<controls:WrapPanel
Width="{Binding ElementName=ScrollViewer1, Path=Width}"
Height="{Binding ElementName=ScrollViewer1, Path=Height}">
Hope that helps.
Ian

Related

WPF set new control position relative within a grid

This is somewhat a duplicate of other questions so apologies in advance but I haven't been able to make sense of the existing answers (probably because I'm a WPF newb).
I have a grid within a canvas. The grid is added programmatically, not in xaml and is much smaller than the canvas. I want to programmatically add a control (text box) at the position the user clicks on the grid. The application may or may not be full screen and users screen resolutions may differ.
Currently I'm using a mouse down event and getting a point:
Dim p As Point = Mouse.GetPosition(myGrid)
And then using the point.x and point.y with Canvas.SetLeft and Canvas.SetTop but this only works when the app is full screen and the screen res is consistent.
I know it's bad form to ask for code but please include a snippet in your answer as I've been wrestling with this for some time & going round in circles. I'm using VB but answers in any language will be welcome. Thanks very much.
Grid arranges its children basically mostly on the child's Margin property.
So do this OnClick of your grid:
// dont forget to add an event handler on creating the grid
Grid myGrid = new Grid();
myGrid.MouseDown += myGrid_MouseDown;
private void myGrid_MouseDown(object sender, MouserEventArgs e)
{
Point p = e.GetPosition(myGrid);
TextBox tb = new TextBox();
tb.Margin = new Thickness(p.X, p.Y, 0, 0);
tb.HorizontalAlignment = HorizontalAlignment.Left;
tb.VerticalAlignment = VerticalAlignment.Top; // cuz we set margin on Top and Left sides..
myGrid.Children.Add(tb);
}
Hope it helps :)
I think that the problem is not on your code but in your xaml.
Mouse.GetPosition(myGrid)
should works well.
I think that your Grid is not the same size as your Canvas.
Try something like this:
<DockPanel>
<Canvas x:Name="can">
<Grid Height="{Binding ElementName=can, Path=ActualHeight}" Width="{Binding ElementName=can, Path=ActualWidth}" Background="Red" PreviewMouseDown="Grid_PreviewMouseDown" />
</Canvas>
</DockPanel>

Autosize canvas in wpf

How can canvas in wpf be autosized? I have a canvas in scrollviewer and I will add several buttons and lines in this canvas in code behind. since I don't know the position of the buttons, I have to hard code a very large number for the width and height of the canvas or if I add too many buttons, it can only show part of them.
I try to set the Width and Height to Auto but it doesn't work.
<Grid>
<ScrollViewer HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible">
<Canvas Width="Auto" Height="Auto" Name="cv1"></Canvas>
</ScrollViewer>
</Grid>
The Canvas element is the only element that can not be automatically resized, because has no inherent layout characteristics. If you want the Control to be resized as child elements come in, you could use something deriving from Grid.
Try a UniformGrid instead of your Canvas ans fill it with the elements you want. It allows you to just add elements without any layout constraints that are handled by the UniformGrid. otherwise if you use a simple Grid, you will have to define a Position for your element by setting the Margin property of each child element.
Hope this helps.

Programmatically position control in WPF

I am creating a karaoke program in WPF. Basically, I have a MediaElement which plays vidioes and such, and a StackPanel atop of that which I use to render stuff on top of the MediaElement.
I am trying to programmatically add a TextBlock to the StackPanel, which is going display the lyrics. The problem is that the TextBlock ends up in the top left corner no matter what I write.
Private LyricLabel As New TextBlock
Sub New(Panel As StackPanel)
With LyricLabel
.Foreground = Brushes.White
.FontFamily = New FontFamily("Verdana")
.FontSize = 20
.HorizontalAlignment = HorizontalAlignment.Stretch
.VerticalAlignment = VerticalAlignment.Bottom
End With
Panel.Children.Add(LyricLabel)
End Sub
Also, I want a ball or something to jump from word to word. Is there a easy way to get the width of each of the words + the space between them, or do I have to calculate that by myself?
It would be a better option to use a Grid and do that entirely in XAML. The Grid has the property that if many elements are in the same cell, they all overlap. So you put the MediaElement and a TextBlock together, with proper alignments and you're done:
<Grid>
<MediaElement/>
<TextBlock Text="{Binding CurrentLyric}" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="0 0 0 30"/>
</Grid>
You just have to provide a property for dropping the current text to be shown for the binding to work, and it will adjust it for you.

WPF ZoomControl and Adorners

This my first post on stack overflow, I hope I get it right. I am using the ZoomControl from WPF Extensions to display an image with pan and zoom support:
<DockPanel Grid.Row="1" x:Name="canvas">
<Controls:ZoomControl x:Name="zoomControl">
<Canvas x:Name="canvas">
<Image x:Name="imageControl" Stretch="None" />
</Canvas>
</Controls:ZoomControl>
</DockPanel>
When the user selects an image with a bowse dialog, I load that image like so:
bmp = new BitmapImage(new Uri(fileName));
this.imageControul.Source = bmp;
I would like to added rectangles\adorners to specific locations (pixel coordinates) on the image the user loaded based on some image processing.
var r = new Rectangle();
r.StrokeThickness = 5;
r.Stroke = Brushes.Black;
r.Fill = Brushes.Transparent;
r.Width = width;
r.Height = height;
Canvas.SetLeft(r, y);
Canvas.SetTop(r, x);
canvas.Children.Add(r);
However, the rectangles are not placed in the expected locations? Wrong scale and location.
Thanks,
John
I expect the problem is that your Canvas is expanding to fill the space rather than being locked to the rectangle. Have a look with a tool like Snoop and see what the bounding boxes of the two are.
You might be able to fix it with Horizontal and VercticalAlignment on the canvas, set them to anything other than Stretch.
If that doesn't work restructure it like this
<ZoomBox>
<Grid>
<Image/>
<Canvas/>
</Grid>
</ZoomBox>
So the Image and the canvas are grouped by the parent Grid which is being transformed.

scrolling the silverlight ScrollViewer programmatically

i have a silverlight scrollviewer in my xaml page as below
<ScrollViewer x:Name="scroller" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Hidden" Height="140" BorderBrush="{x:Null}">
contents here
</ScrollViewer >
and i am trying to move the scroll bar programmatically as below but it didnt worked out
scroller.ScrollToHorizontalOffset(250);
scroller.lineleft();
scroller.moveleft();
this.UpdateLayout();
Upperscroller.UpdateLayout();
can any body guide me how to move the scrollbar programmatically
As a test, this code hooked up to button moves the scrollbar with nothing else required:
scroller.ScrollToHorizontalOffset(scroller.HorizontalOffset + 10);
The content was very wide though. AnthonyWJones is correct in his comment. The content must be at least 250 + the width of your scrollviewer to have any effect. HorizontalOffset is the offset of the left side of the scrollview content.
Try smaller values when testing :)

Resources