Archives / 2009 / November
  • Silverlight: Working with ActualHeight & ActualWidth at Runtime

    Tags: Silverlight

    I came up against a problem, it seems like a pretty specific problem, but none the less the solution took me a while to figure out, so worth sharing!

    My problem: I have a user control that contains some text among other things, but the text is of various length, the containing textblock therefore, like the user control has a dynamic height (set the Height property to System.Double.NaN).

    There are n instances of the user control within a StackPanel, as a control is added to the StackPanel I want a StoryBoard which animates the Height and the Opacity.  The Height of course I do not know.

    So I need to the set the Value of the Double Animation at runtime.

    The XAML for the StoryBoard.

    Code Snippet
    1. <Storyboard x:Name="sbExpandControl">
    2.     <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="(FrameworkElement.Height)">
    3.         <EasingDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
    4.         <EasingDoubleKeyFrame KeyTime="00:00:02" Value="100" x:Name="expandToHeight"/>
    5.     </DoubleAnimationUsingKeyFrames>
    6.     <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="(UIElement.Opacity)">
    7.         <EasingDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
    8.         <EasingDoubleKeyFrame KeyTime="00:00:02" Value="1"/>
    9.     </DoubleAnimationUsingKeyFrames>
    10. </Storyboard>

    Firstly I need to new up the user control, set all the properties, add the control to the StackPanel, set the height of the DoubleAnimation and fire the StoryBoard.

    Just simply going UserControl.ActualHeight will return 0 because the layout engine has not calculated the ActualHeight property. Which is the problem!!!

    So we need to use the Dispatcher class (you can find out more on MSDN).

    Code Snippet
    1. UserComment uc = newUserComment()
    2. {
    3.     Comments = v.Comments,
    4. };
    6. stkComments.Children.Insert(0, uc);
    7. stkComments.Dispatcher.BeginInvoke(() =>
    8.     {
    9.         uc.ExpandControl();
    10.     });

    In the User Control (UserComment)

    Code Snippet
    1. publicvoid ExpandControl()
    2. {
    3.     expandToHeight.Value = this.ActualHeight;
    4.     sbExpandControl.Begin();
    5. }

    Hope this helps!


  • Silverlight DataGrid: Scroll with mouse wheel&hellip;quick and dirty!

    Tags: Silverlight

    By Default scrolling with the mouse wheel is not enabled in the Silverlight DataGrid, actually I don’t think any control has it enabled.

    Personally I think its pretty standard functionality for things to scroll with the mouse wheel.

    So, I have got this little chunk of code that takes does the trick, nothing fancy going on here, but it works a treat.

    Code Snippet
    1. privatevoid dgResults_MouseWheel(object sender, MouseWheelEventArgs e)
    2. {
    3.     if (!e.Handled)
    4.     {
    5.         int rowsToMove = 0;
    6.         if (e.Delta < 0)
    7.         {
    8.             rowsToMove = e.Delta / 120 * -1;
    9.         }
    10.         else
    11.         {
    12.             rowsToMove = e.Delta / 120 * -1;
    13.         }
    15.         if (dgResults.SelectedIndex == 0
    16.                 || dgResults.SelectedIndex == (dgResults.ItemsSource.Cast<ItemSourceType>().ToList().Count - 1))
    17.         { return; }
    19.         dgResults.SelectedIndex = dgResults.SelectedIndex + rowsToMove;
    20.         dgResults.ScrollIntoView(dgResults.SelectedItem, dgResults.Columns[0]);
    21.     }
    22. }

    To explain a little…I found that my delta would change in multiples of 120, depending on how fast I scrolled, –120 if I scrolled down, +120 is I scrolled up.  I needed to change this as if I scrolled down I needed the SelectedIndex to increase, so that’s what the first bit does.

    Then I check that I’m not at either 0 or the last item in the datagrid, set the selected index and use the ScrollToView() method.

    You may need to change slightly if you have horizontal scrolling, to stay with the correct column, for me having the first column is more than ideal, perfect in fact.

    Note: This code has been tested nowhere except on  my dev machine. So, here goes!!