Silverlight: Auto Scrolling down with Scrollviewer - silverlight

I have a scrollviewer with dynamic content. On an event, a new content is made visible and the scrollbar appears. How do i make it auto scroll to have that content in view?
Thanks,
Shawn Mclean

Use ScrollToVerticalOffset() to do this, passing in the coordinates of the new content.
var newContent = GetNewContent();
var generalTransform = newContent.TransformToVisual(
Application.Current.RootVisual as UIElement);
Point offset = generalTransform.Transform(new Point(0, 0));
double controlTop = offset.Y;
double controlLeft = offset.X;
scrollViewer.ScrollToVerticalOffSet(controlTop);
scrollViewer.ScrollToHorizontalOffSet(controlLeft);

Are you sure Scrollviewer is the control you need here?
Sounds to me like you ought to be using ListBox (which you can heavily style if necessary). It has a ScrollIntoView(item) method which would acheive your goal.

Related

StackPanel orientation set in code behind

I want to set my StackPanel Orientation property to vertical in code behind. I cant find Enum that I can set Vertical.
var panel = new StackPanel();
panel.Orientation = Vertical;
After some research I found from MSDN
var panel = new StackPanel();
panel.Orientation = Orientation.Vertical;
May be helpful for researchers

How to add borders to WPF ListView in code

I have created a ListView with a GridView in code.
ListView gridList = new ListView();
GridView gridListView = new GridView ();
gridList.View = gridListView;
Now, I define a GridViewColumn, set the header, width and bindingPath. All good and the data shows up.
GridViewColumn listColumn = new GridViewColumn();
listColumn.Header = "Some Header";
listColumn.Width = 100.0;
listColumn.DisplayMemeberBinding = new Binding("Name");
gridListView.Columns.Add(listColumn);
But there are no borders/gridlines shown on display of this ListView. How can I add borders through code?
Someone described my exact problem here but no good solution mentioned
http://social.msdn.microsoft.com/Forums/en-US/fa4fa8e0-81fe-487a-8763-590062d29c06/wpf-listview-gridview-row-border?forum=wpf
The logic in WPF programming is totally different from what you've done in winforms. Everything related to UI should always be set up using XAML (as much as possible). The WPF library itself has many parts desgined mainly for use in XAML although there is always an equivalent codebehind. However that's when using codebehind may be awkward and non-intuitive (as well as straight-forward).
I understand that you want something like the ListView Grid in Winforms. In WPF that can be achieved easily if you use XAML code. Even in code behind, you can always build a Style or Template from XAML string (with the help of XamlReader). This approach is good for complex scenario but in this case I have another approach (don't use the XAML parser at all). This trick does render the grid which is good enough (and at best it can do for the trade-off of simplicity):
//we need an instance of Style to set to ListView.ItemContainerStyle
var style = new Style(typeof(ListViewItem));
//set the bottom border thickness to 1
var setter = new Setter(Control.BorderThickness, new Thickness(0,0,0,1));
style.Setters.Add(setter);
//set the border brush
var borderBrush = new LinearGradientBrush { StartPoint = new Point(0,0),
EndPoint = new Point(1,0)};
var gradStop = new GradientStop(Colors.Transparent, 0.001);
borderBrush.GradientStops.Add(gradStop);
gradStop = new GradientStop(Colors.Green, 0.001);
borderBrush.GradientStops.Add(gradStop);
gradStop = new GradientStop(Colors.Green, 0.999);
borderBrush.GradientStops.Add(gradStop);
gradStop = new GradientStop(Colors.Transparent, 0.999);
borderBrush.GradientStops.Add(gradStop);
setter = new Setter(Control.BorderBrush, borderBrush);
style.Setters.Add(setter);
yourListView.ItemContainerStyle = style;
Note that the default inner Border of each ListViewItem has a hard-coded CornerRadius of about 2, so by setting just the bottom BorderBrush to a solid brush such as Brushes.Green will show a little upwards curly line at the 2 ends of the bottom border. You can try it yourself. If this result is acceptable, the code can be shorter and simpler (because you don't have to define the GradientBrush to cut-off the 2 curly ends) like this:
setter = new Setter(Control.BorderBrush, Brushes.Green);
style.Setters.Add(setter);
If the behavior is still not what you want. You should try the approach I mentioned about using XamlReader to parse a XAML string and get an instance of whatever you want in codebehind. (you can search it yourself, it's easy to have some result).
I suggest you see this link, it contains a dynamic GridView created in code-behind that can be useful for your specific case. For the code sample that you provided, you didn't add ShowGridLines property.

How to change the background of a grid to an image in WP7 silverlight?

I'm trying to set a background for a grid control in WP7 silverlight, I need to do that programatically, not in the desighn.
I tried something like:
ContentPanel.Background = new BitmapImage(new Uri("Images\Backgrounds\with box\13.jpg", UriKind.Relative));
But of course, I got an error, because on the right hand we should have the type SolidColorBrush.
is there a way to do that?
Thanks..
I would firstly recommend that you use a Canvas instead of a Grid. You can do this by deleting the Grid and inserting a Canvas through the Toolbox -> Drag and Drop.
Then, you can use the code as simple as:
ImageBrush imageBrush = new ImageBrush();
imageBrush.ImageSource = new BitmapImage(new Uri("url", UriKind.Relative));
CanvasName.Background = imageBrush;
That will change the background to whatever you want.
Hope that helps.

take a screenshot of WPF datagrid with scrollviewer

I'm trying to take a screenshot of a datagrid which has to many rows to be displayed. So there is a scrollviewer.
So when I just put the datagrid into the Render Method of RenderTargetBitmap I obviously just get the viewable part of the datagrid.
I read that one can take a screenshot of a content when actually rendering the ItemsPresenter of the ScrollViewer of that control, as the ItemsPresenter would have the "real" Width and Height of the content.
Unfortunatly my ScrollViewer doesnt have any different Height, ActualHeight or RenderSize.Height than the dataGrid.
So I always just get the visible part of the Content.
Anyone know how to do this the right way, that it actually takes the whole content ?
Code:
var scroll = GetTemplateChildByName(dataGridInOut);
if (scroll != null)
{
var item = scroll.Content as ItemsPresenter;
var width = item.RenderSize.Width;
var height = item.RenderSize.Height;
var rtb = new RenderTargetBitmap((int) Math.Round(width), (int)Math.Round(height), 96, 96,
PixelFormats.Pbgra32);
var drawingVisual = new DrawingVisual();
var visualBrush = new VisualBrush(item);
using (var context = drawingVisual.RenderOpen())
{
context.DrawRectangle(visualBrush, null, new Rect(new Point(0,0), new Size(width, height)));
}
rtb.Render(drawingVisual);
Clipboard.SetImage(rtb);
}
Leaf is right. You could instantiate another DataGrid bound to the same source programmatically, put it into a container which gives it infinite space, wait for it to render and then take a screenshot of this. No need to actually show it in the UI.

WPF TextBox recalculate size

When using a wpf textbox without explicit height and width values, and when there is space available to expand, the textbox resizes as you type.
However when I change the border thickness, it does not recalculate it and for very thick borders, part of the text is covered by the border. How do I explicitly precipitate a recalc?
Coincidently I am using a derived custom textbox class so I should know when the border thickness changes.
This bug must be some optimization gone wrong
Overriding Metadata for BorderThickness or adding a Dependency Property that affects Measure, Arrange or Render don't help
Undocking and Redocking from the parent container had no effect either
Even Undocking from the parent container and Redocking into a new container won't help if the space it is given in the new container is exactly the same as the space that it had in the old container
It seems like the size is only re-calculated once Text, Width, Height or available space changes. I looked around with Reflector but things get pretty complex down there so I couldn't find the source for this.
Here is a small workaround that listens to changes in BorderThickness and in the changed event handler, make a small change to the Width and once it is updated, change it right back
public class MyTextBox : TextBox
{
public MyTextBox()
{
DependencyPropertyDescriptor borderThickness
= DependencyPropertyDescriptor.FromProperty(MyTextBox.BorderThicknessProperty, typeof(MyTextBox));
borderThickness.AddValueChanged(this, OnBorderThicknessChanged);
}
void OnBorderThicknessChanged(object sender, EventArgs e)
{
double width = this.Width;
SizeChangedEventHandler eventHandler = null;
eventHandler = new SizeChangedEventHandler(delegate
{
this.Width = width;
this.SizeChanged -= eventHandler;
});
this.SizeChanged += eventHandler;
this.Width = this.ActualWidth + 0.00000001;
}
}
First of all, this looks like a bug.
If the problem is that dynamic changes of the border thickness are not taken into account, you can perhaps make a workaround by creating a dependency property with AffectsMeasure in FrameworkPropertyMetadata, and bind it to the border thickness. Hope this quirk helps.
If the static setting of the border thickness are not taken into account, you can try to replace the TextBox's default template with your own (correct) version.

Resources