This is a migrated thread and some comments may be shown as answers.

Need to update scrollviewer on expand

11 Answers 165 Views
Expander
This is a migrated thread and some comments may be shown as answers.
Chaitanya Damley
Top achievements
Rank 1
Chaitanya Damley asked on 08 Jul 2010, 01:51 PM
Hi,

I am adding radexpander elements to a scrollviewer control on runtime. Suppose the last expander element is located right at the bottom of the scrollviewer's viewport.My requirement is that when the user expands that particular radexpander element, the scrollviewer should move downwards so that the expander's content gets visible which as of now goes beyond the scrollviewer's viewport and the user has to manually scroll down to see the content.

11 Answers, 1 is accepted

Sort by
0
Kiril Stanoev
Telerik team
answered on 13 Jul 2010, 02:14 PM
Hi Chaitanya,

When the last expander expands, you can use ScrollViewer's ScrollToVerticalOffset method. Also, take a look at this StackOverflow thread as it explains how make the Silverlight ScrollViewer scroll to show a child control with focus?
Let me know if need further assistance.

On a side note, I'd like to inform you that we've just released an online tool that allows you to reduce the size of your Silverlight applications. For more information, please visit http://blogs.telerik.com/blogs/posts/10-06-10/telerik_assembly_minifier.aspx

Kind regards,
Kiril Stanoev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Chaitanya Damley
Top achievements
Rank 1
answered on 14 Jul 2010, 07:59 AM
I have already tried the ScrollToVerticalOffset and stackoverflow solution mentioned above but to no avail...Can you please tell me how logical scrolling could be implemented because none of the physical scrolling solutions seem to be working...Please let me know the required assemblies also...
0
Kiril Stanoev
Telerik team
answered on 16 Jul 2010, 01:33 PM
Hello Chaitanya,

Please find attached a sample project demonstrating one possible solution to this scenario.

Best wishes,
Kiril Stanoev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Chaitanya Damley
Top achievements
Rank 1
answered on 19 Jul 2010, 10:36 AM
Hi,

Thanks for the solution. Its working much better now. But its slightly inconsistent. As in, the scrollviewer position gets updated for later layout updates (especially for the last elements in the extent) but its not the case during the first layout update for them.
0
Kiril Stanoev
Telerik team
answered on 21 Jul 2010, 02:38 PM
Hi Chaitanya,

Do you find the usage of a Dispatcher inconsistent? If so, the Dispatcher is necessary since the StackPanel that holds the Expanders has not yet updated its height. If you change the expanded event handler to the one bellow you will see that 2 different values appear:

void expander_Expanded(object sender, RoutedEventArgs e)
{
    RadExpander expander = sender as RadExpander;
    GeneralTransform expanderTransform = expander.TransformToVisual(scrollViewer1);
    Rect rectangle = expanderTransform.TransformBounds(new Rect(new Point(expander.Margin.Left, expander.Margin.Top), expander.RenderSize));
    double newOffset = scrollViewer1.VerticalOffset + ((rectangle.Bottom + 100) - scrollViewer1.ViewportHeight);
    var before = (scrollViewer1.Content as StackPanel).ActualHeight;
    MessageBox.Show("Before dispatcher: " + before);
    Dispatcher.BeginInvoke(() =>
    {
        var after = (scrollViewer1.Content as StackPanel).ActualHeight;
        MessageBox.Show("Before dispatcher: " + after);
        scrollViewer1.ScrollToVerticalOffset(newOffset);
    });
}


Best wishes,
Kiril Stanoev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Chaitanya Damley
Top achievements
Rank 1
answered on 21 Jul 2010, 04:57 PM
yes you are right....i also discovered that the code works fine when i have a debug point in the method or i display a message box before calling the dispatcher...If i don't do this, the behaviour is inconsistent...Any suggestions?
0
Chaitanya Damley
Top achievements
Rank 1
answered on 22 Jul 2010, 12:13 PM
Also, if i use your above code, the behaviour is correct but it becomes inconsistent when i remove those 2 message boxes...?????
0
Kiril Stanoev
Telerik team
answered on 23 Jul 2010, 07:39 AM
Hello Chaitanya,

Unfortunately I am not able to reproduce the issue. Could you please send me a sample project demonstrating the problem. This way I will be better able to assist you.

All the best,
Kiril Stanoev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Chaitanya Damley
Top achievements
Rank 1
answered on 06 Sep 2010, 03:15 PM
This is what i am trying exactly.....

 

Imports

 

System

 

 

 

 

Imports

 

System.Collections.Generic

 

 

 

 

Imports

 

System.Linq

 

 

 

 

Imports

 

System.Windows

 

 

 

 

Imports

 

System.Windows.Controls

 

 

 

 

Imports

 

System.Windows.Documents

 

 

 

 

Imports

 

System.Windows.Input

 

 

 

 

Imports

 

System.Windows.Media

 

 

 

 

Imports

 

System.Windows.Media.Animation

 

 

 

 

Imports

 

System.Windows.Shapes

 

 

 

 

Imports

 

System.Windows.Navigation

 

 

 

 

Imports

 

TDSolsticeSKUSelector.SKUSelectorProxy

 

 

 

 

Imports

 

System.Windows.Data

 

 

 

 

Imports

 

System.Windows.Browser

 

 

 

 

Imports

 

Telerik.Windows.Controls

 

 

 

 

Imports

 

System.Windows.Controls.ToolKit

 

 

 

 

Imports

 

System.ServiceModel

 

 

 

 

 

Partial

 

Public Class StartScreen

 

 

Inherits UserControl

 

 

Dim newOffset As FrameworkElement

 

 

Public Sub New()

 

InitializeComponent()

AddExpander()

 

End Sub

 

 

 

 

 

 

Private Sub UpdateScroller()

 

 

' MessageBox.Show(expStack.ActualHeight)

 

 

 

 

 

expSV.ScrollIntoView(newOffset)

 

End Sub

 

 

 

 

 

 

Private Sub expanderPanel_Collapsed(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs)

 

 

AddHandler expSV.LayoutUpdated, AddressOf expSV_LayoutUpdated

 

 

 

End Sub

 

 

 

 

 

 

Private Sub expanderPanel_Expanded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs)

 

 

 

AddHandler expSV.LayoutUpdated, AddressOf expSV_LayoutUpdated

 

 

 

End Sub

 

 

 

 

 

 

Private Sub AddExpander()

 

 

For i As Integer = 0 To 10

 

 

Dim expanderPanel As New RadExpander

 

 

AddHandler expanderPanel.Expanded, AddressOf expanderPanel_Expanded

 

 

AddHandler expanderPanel.Collapsed, AddressOf expanderPanel_Collapsed

 

Telerik.Windows.Controls.Animation.AnimationManager.SetIsAnimationEnabled(expanderPanel,

True)

 

Telerik.Windows.Controls.Animation.AnimationManager.AnimationSpeedRatio = 0.35

 

 

Dim grdHeader As Grid = New Grid()

 

 

 

Dim column0 As New ColumnDefinition

 

column0.Width =

New GridLength(25)

 

grdHeader.ColumnDefinitions.Add(column0)

 

Dim column1 As New ColumnDefinition

 

column1.Width =

New GridLength(250)

 

grdHeader.ColumnDefinitions.Add(column1)

 

Dim column2 As New ColumnDefinition

 

column2.Width =

New GridLength(5)

 

grdHeader.ColumnDefinitions.Add(column2)

 

Dim column3 As New ColumnDefinition

 

column3.Width =

New GridLength(330)

 

grdHeader.ColumnDefinitions.Add(column3)

 

Dim column4 As New ColumnDefinition

 

column4.Width =

New GridLength(55)

 

grdHeader.ColumnDefinitions.Add(column4)

 

Dim column5 As New ColumnDefinition

 

column5.Width =

New GridLength(75)

 

grdHeader.ColumnDefinitions.Add(column5)

 

 

Dim txtComName As New TextBlock

 

txtComName.TextAlignment = TextAlignment.Center

txtComName.FontWeight = FontWeights.Bold

txtComName.Foreground =

New SolidColorBrush(Colors.Black)

 

txtComName.TextWrapping = TextWrapping.Wrap

txtComName.Text =

"Company" + Convert.ToString(i)

 

 

 

txtComName.SetValue(Grid.ColumnProperty, 1)

grdHeader.Children.Add(txtComName)

 

Dim txtPart2 As New TextBlock

 

txtPart2.Foreground =

New SolidColorBrush(Colors.Black)

 

txtPart2.Text =

"|"

 

 

 

 

 

txtPart2.SetValue(Grid.ColumnProperty, 2)

grdHeader.Children.Add(txtPart2)

 

Dim txtContName As New TextBlock

 

txtContName.TextAlignment = TextAlignment.Center

txtContName.FontWeight = FontWeights.Bold

txtContName.Foreground =

New SolidColorBrush(Colors.Black)

 

txtContName.TextWrapping = TextWrapping.Wrap

txtContName.Text =

"ContactName" + Convert.ToString(i)

 

txtContName.SetValue(Grid.ColumnProperty, 3)

grdHeader.Children.Add(txtContName)

 

Dim txtPart4 As New TextBlock

 

txtPart4.Foreground =

New SolidColorBrush(Colors.Black)

 

txtPart4.Text =

"|"

 

 

 

 

 

txtPart4.SetValue(Grid.ColumnProperty, 4)

grdHeader.Children.Add(txtPart4)

 

Dim btnSelect As New Button

 

btnSelect.Width = 55

btnSelect.Cursor = Cursors.Hand

btnSelect.SetValue(Grid.ColumnProperty, 5)

grdHeader.Children.Add(btnSelect)

expanderPanel.Header = grdHeader

 

 

 

'Panel Content

 

 

 

 

 

 

Dim grdContent As Grid = New Grid()

 

 

 

Dim columnA As New ColumnDefinition

 

columnA.Width =

New GridLength(100)

 

grdContent.ColumnDefinitions.Add(columnA)

 

'column added

 

 

 

 

 

 

Dim columnAC As New ColumnDefinition

 

columnAC.Width =

New GridLength(150)

 

grdContent.ColumnDefinitions.Add(columnAC)

 

Dim columnPart1 As New ColumnDefinition

 

columnPart1.Width =

New GridLength(5)

 

grdContent.ColumnDefinitions.Add(columnPart1)

 

 

 

 

Dim columnB As New ColumnDefinition

 

columnB.Width =

New GridLength(150)

 

grdContent.ColumnDefinitions.Add(columnB)

 

 

'column added

 

 

 

 

 

 

Dim columnBC As New ColumnDefinition

 

columnAC.Width =

New GridLength(200)

 

grdContent.ColumnDefinitions.Add(columnBC)

 

 

Dim columnPart2 As New ColumnDefinition

 

columnPart2.Width =

New GridLength(5)

 

grdContent.ColumnDefinitions.Add(columnPart2)

 

 

'column added

 

 

 

 

 

 

Dim columnCA As New ColumnDefinition

 

columnCA.Width =

New GridLength(100)

 

grdContent.ColumnDefinitions.Add(columnCA)

 

 

Dim columnC As New ColumnDefinition

 

columnC.Width =

New GridLength(140)

 

grdContent.ColumnDefinitions.Add(columnC)

 

Dim rowA As New RowDefinition

 

rowA.Height =

New GridLength(5)

 

grdContent.RowDefinitions.Add(rowA)

 

'Dim rowAC As New RowDefinition

 

 

 

 

 

 

'rowAC.Height = New GridLength(5)

 

 

 

 

 

 

'grdContent.RowDefinitions.Add(rowAC)

 

 

 

 

 

 

 

 

Dim rowB As New RowDefinition

 

 

'rowB.Height = New GridLength(25)

 

 

 

 

 

 

'rowB.

 

 

 

 

 

grdContent.RowDefinitions.Add(rowB)

 

Dim rowC As New RowDefinition

 

 

'rowC.Height = New GridLength(25)

 

 

 

 

 

grdContent.RowDefinitions.Add(rowC)

 

Dim rowD As New RowDefinition

 

rowD.Height =

New GridLength(25)

 

grdContent.RowDefinitions.Add(rowD)

 

Dim rowE As New RowDefinition

 

rowE.Height =

New GridLength(10)

 

grdContent.RowDefinitions.Add(rowE)

 

Dim tbHeading1 As New TextBlock

 

tbHeading1.Text =

"Company Name : "

 

 

 

 

 

tbHeading1.TextAlignment = TextAlignment.Right

tbHeading1.SetValue(Grid.ColumnProperty, 0)

tbHeading1.SetValue(Grid.RowProperty, 1)

grdContent.Children.Add(tbHeading1)

 

 

Dim tbComName As New TextBlock

 

 

 

' tbComName.AcceptsReturn = True

 

 

 

 

 

 

'tbComName.IsReadOnly = True

 

 

 

 

 

tbComName.Text =

"CompanyName" + Convert.ToString(i)

 

tbComName.TextAlignment = TextAlignment.Left

 

tbComName.TextWrapping = TextWrapping.Wrap

tbComName.SetValue(Grid.ColumnProperty, 1)

tbComName.SetValue(Grid.RowProperty, 1)

grdContent.Children.Add(tbComName)

 

Dim tbContName As New TextBlock

 

 

'Dim str3 As String

 

 

 

 

 

 

Dim tbHeading As New TextBlock

 

tbHeading.Text =

"Contact Name : "

 

 

 

 

 

tbHeading.TextAlignment = TextAlignment.Right

 

 

tbHeading.SetValue(Grid.ColumnProperty, 0)

tbHeading.SetValue(Grid.RowProperty, 2)

grdContent.Children.Add(tbHeading)

tbContName.Text =

"ContactName" + Convert.ToString(i)

 

tbContName.TextAlignment = TextAlignment.Left

 

 

tbContName.TextWrapping = TextWrapping.Wrap

 

'str3 = tbComName.Text.Substring(7, 1)

 

 

 

 

 

 

'tbComName.Text.Replace(str3, " ")

 

 

 

 

 

 

tbContName.SetValue(Grid.ColumnProperty, 1)

tbContName.SetValue(Grid.RowProperty, 2)

grdContent.Children.Add(tbContName)

 

'str3 = tbContName.Text.Replace(tbContName.Text.Substring(7, 1), " ")

 

 

 

 

 

 

'tbContName.Text = str3

 

 

 

 

 

 

 

Dim txtPart5 As New TextBlock

 

txtPart5.Text =

"|"

 

 

 

 

 

txtPart5.SetValue(Grid.ColumnProperty, 2)

txtPart5.SetValue(Grid.RowProperty, 1)

grdContent.Children.Add(txtPart5)

 

Dim txtPart6 As New TextBlock

 

txtPart6.Text =

"|"

 

 

 

 

 

txtPart6.SetValue(Grid.ColumnProperty, 2)

txtPart6.SetValue(Grid.RowProperty, 2)

grdContent.Children.Add(txtPart6)

 

 

Dim tbHeading3 As New TextBlock

 

tbHeading3.Text =

"Email : "

 

 

 

 

 

tbHeading3.TextAlignment = TextAlignment.Right

 

 

tbHeading3.SetValue(Grid.ColumnProperty, 3)

tbHeading3.SetValue(Grid.RowProperty, 1)

grdContent.Children.Add(tbHeading3)

 

 

Dim tbHeading4 As New TextBlock

 

tbHeading4.Text =

"Telephone Number : "

 

 

 

 

 

tbHeading4.TextAlignment = TextAlignment.Right

 

tbHeading4.SetValue(Grid.ColumnProperty, 3)

tbHeading4.SetValue(Grid.RowProperty, 2)

grdContent.Children.Add(tbHeading4)

 

 

Dim tbEmail As New TextBlock

 

 

'Dim str3 As String

 

 

 

 

 

 

'If (obj.Email.Length > 50) Then

 

 

 

 

 

 

' str3 = obj.Email.Substring(0, 50)

 

 

 

 

 

 

' len1 = obj.Email.Length - str3.Length

 

 

 

 

 

 

' str4 = obj.Email.Substring(51, len1 - 1)

 

 

 

 

 

 

' tbEmail.TextAlignment = TextAlignment.left

 

 

 

 

 

 

' tbEmail.Text = "Email : " + str3 & Environment.NewLine + str4

 

 

 

 

 

 

'Else

 

 

 

 

 

tbEmail.TextAlignment = TextAlignment.Left

tbEmail.VerticalAlignment = Windows.VerticalAlignment.Stretch

tbEmail.TextWrapping = TextWrapping.Wrap

tbEmail.Text =

"Email" + Convert.ToString(i)

 

 

'End If

 

 

 

 

 

tbEmail.SetValue(Grid.ColumnProperty, 4)

tbEmail.SetValue(Grid.RowProperty, 1)

grdContent.Children.Add(tbEmail)

 

Dim txtPart7 As New TextBlock

 

txtPart7.Text =

"|"

 

 

 

 

 

txtPart7.SetValue(Grid.ColumnProperty, 5)

txtPart7.SetValue(Grid.RowProperty, 1)

grdContent.Children.Add(txtPart7)

 

Dim tbPhone As New TextBlock

 

tbPhone.Text =

"Telephone" + Convert.ToString(i)

 

tbPhone.TextAlignment = TextAlignment.Left

tbPhone.SetValue(Grid.ColumnProperty, 4)

tbPhone.SetValue(Grid.RowProperty, 2)

grdContent.Children.Add(tbPhone)

 

Dim txtPart8 As New TextBlock

 

txtPart8.Text =

"|"

 

 

 

 

 

txtPart8.SetValue(Grid.ColumnProperty, 5)

txtPart8.SetValue(Grid.RowProperty, 2)

grdContent.Children.Add(txtPart8)

 

Dim tbHeading5 As New TextBlock

 

tbHeading5.Text =

"End User Type : "

 

 

 

 

 

tbHeading5.TextAlignment = TextAlignment.Right

tbHeading5.SetValue(Grid.ColumnProperty, 6)

tbHeading5.SetValue(Grid.RowProperty, 1)

grdContent.Children.Add(tbHeading5)

 

 

Dim tbHeading6 As New TextBlock

 

tbHeading6.Text =

"City : "

 

 

 

 

 

tbHeading6.TextAlignment = TextAlignment.Right

 

tbHeading6.SetValue(Grid.ColumnProperty, 6)

tbHeading6.SetValue(Grid.RowProperty, 2)

grdContent.Children.Add(tbHeading6)

 

Dim tbEUType As New TextBlock

 

tbEUType.Text =

"EndUserType"

 

 

 

 

 

tbEUType.TextAlignment = TextAlignment.Left

tbEUType.TextWrapping = TextWrapping.Wrap

tbEUType.SetValue(Grid.ColumnProperty, 7)

tbEUType.SetValue(Grid.RowProperty, 1)

grdContent.Children.Add(tbEUType)

 

Dim tbCity As New TextBlock

 

tbCity.Text =

"City"

 

 

 

 

 

tbCity.TextAlignment = TextAlignment.Left

tbCity.TextWrapping = TextWrapping.Wrap

tbCity.SetValue(Grid.ColumnProperty, 7)

tbCity.SetValue(Grid.RowProperty, 2)

grdContent.Children.Add(tbCity)

 

Dim btnViewDetails As New Button

 

btnViewDetails.Width = 80

btnViewDetails.HorizontalAlignment = Windows.HorizontalAlignment.Left

btnViewDetails.Cursor = Cursors.Hand

btnViewDetails.SetValue(Grid.ColumnProperty, 4)

btnViewDetails.SetValue(Grid.RowProperty, 3)

grdContent.Children.Add(btnViewDetails)

expanderPanel.Content = grdContent

expanderPanel.ExpandDirection = Telerik.Windows.Controls.ExpandDirection.Down

expStack.Children.Add(expanderPanel)

 

Dim firstChild = TryCast(VisualTreeHelper.GetChild(expanderPanel, 0), FrameworkElement)

 

 

If Not firstChild Is Nothing Then

 

 

 

 

 

 

Dim button = TryCast(firstChild.FindName("HeaderButton"), System.Windows.Controls.Control)

 

button.Tag = i

 

End If

 

 

 

 

 

 

Next

 

 

 

 

 

 

End Sub

 

 

 

 

 

 

 

 

Private Sub expSV_LayoutUpdated(ByVal sender As System.Object, ByVal e As System.EventArgs)

 

 

Dim focusedElement As FrameworkElement = TryCast(FocusManager.GetFocusedElement(), FrameworkElement)

 

 

Dim focusedVisualTransform As GeneralTransform = focusedElement.TransformToVisual(expSV)

 

 

Dim rectangle As Rect = focusedVisualTransform.TransformBounds(New Rect(New Point(focusedElement.Margin.Left, focusedElement.Margin.Top), focusedElement.RenderSize))

 

 

Dim count As Integer = DirectCast(DirectCast(expSV.Content, System.Object), System.Windows.Controls.StackPanel).Children.Count

 

 

Dim foundElement As Boolean = False

 

 

 

 

 

 

Dim i As Integer = 1

 

 

For Each element As RadExpander In DirectCast(DirectCast(expSV.Content, System.Object), System.Windows.Controls.StackPanel).Children

 

 

Dim firstChild = TryCast(VisualTreeHelper.GetChild(element, 0), FrameworkElement)

 

 

If Not firstChild Is Nothing Then

 

 

 

 

 

 

Dim button = TryCast(firstChild.FindName("HeaderButton"), System.Windows.Controls.Control)

 

 

If foundElement Then

 

 

 

 

 

newOffset = firstChild

 

Exit For

 

 

 

 

 

 

End If

 

 

 

 

 

 

If button.Tag = focusedElement.Tag Then

 

 

 

 

 

foundElement =

True

 

 

 

 

 

 

If i = count Then

 

 

 

 

 

newOffset = firstChild

 

Exit For

 

 

 

 

 

 

End If

 

 

 

 

 

 

End If

 

 

 

 

 

 

End If

 

 

 

 

 

i = i + 1

 

Next

 

 

 

 

 

 

'MessageBox.Show(expStack.ActualHeight)

 

 

 

 

 

Dispatcher.BeginInvoke(

AddressOf UpdateScroller)

 

 

RemoveHandler expSV.LayoutUpdated, AddressOf expSV_LayoutUpdated

 

 

End Sub

 

End

 

Class

 

0
Kiril Stanoev
Telerik team
answered on 09 Sep 2010, 01:19 PM
Hello Chaitanya,

Please find attached one possible solution to your scenario.

Greetings,
Kiril Stanoev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Chaitanya Damley
Top achievements
Rank 1
answered on 09 Sep 2010, 05:56 PM
Thanks a lot!!!
Tags
Expander
Asked by
Chaitanya Damley
Top achievements
Rank 1
Answers by
Kiril Stanoev
Telerik team
Chaitanya Damley
Top achievements
Rank 1
Share this question
or