Animate a Scrollviewer without using scrollbar
Hi,
I have a lisbox with a collection of items, I use two buttons to control the listbox's scolling so I hide the listbox default scroller. using a custom template style instancied in a XAML file like this :
The two buttons controls the ListBox's Scrollviewer scrolling using this kind of code:
This works well, but now I'd like to animate the items' scrolling to get a nice visual effect.
So I tried this kind of code :
This dosn't works at all (does nothing).
So I also tried using a storyboard like this:
Dos nothing, like the previous code.
I'm still a very beginer in Noesis / WPF and I'm surely missing something. Do you have any suggestion to make this work ?
Thanks a lot,
Frank
I have a lisbox with a collection of items, I use two buttons to control the listbox's scolling so I hide the listbox default scroller. using a custom template style instancied in a XAML file like this :
Code: Select all
<Canvas x:Name="PanelMakeupBottomLeft" Grid.Row="1" Grid.Column="4" Opacity="1.0" Background="#80FFFFFF" VerticalAlignment="Top" HorizontalAlignment="Right" Width="136" Height="540">
<Button x:Name="BtnScrollUpBottomLeft" Command="{Binding ScrollUp4LooksBottomLeft}" Canvas.Top="5" Canvas.Left="65" Width="24" Height="24" Foreground="{StaticResource BandeauColor}" BorderBrush="{StaticResource BandeauColor}" Background="{StaticResource BandeauColor}" Panel.ZIndex="1">
<Image Source="ArrowUp.png" Stretch="Fill" VerticalAlignment="Center" HorizontalAlignment="Center">
</Image>
</Button>
<ListBox x:Name="BottomLeftMakeupSelector"
Style="{StaticResource Car4LooksListStyle}"
ItemContainerStyle="{StaticResource Car4LooksItemStyle}"
ItemsSource="{Binding LooksBottomLeft}"
DisplayMemberPath="Name"
Height="540"
Width="136">
</ListBox>
<Button x:Name="BtnScrollDownBottomLeft" Command="{Binding ScrollDown4LooksBottomLeft}" Canvas.Left="65" Canvas.Bottom="5" Width="24" Height="24" Foreground="{StaticResource BandeauColor}" BorderBrush="{StaticResource BandeauColor}" Background="{StaticResource BandeauColor}" Panel.ZIndex="1">
<Image Source="ArrowDown.png" Stretch="Fill" VerticalAlignment="Center" HorizontalAlignment="Center" Panel.ZIndex="1">
</Image>
</Button>
</Canvas>
Code: Select all
void ViewModel::ScrollListBoxAnimated(const char* szComponentName, float fScrolValue)
{
Noesis::ListBox* pListBox = FindControl<Noesis::ListBox>(szComponentName);
if (pListBox != nullptr)
{
Noesis::Visual* pVisual = VisualTreeHelper::GetChild(pListBox, 0);
ScrollViewer* pScroll = static_cast<ScrollViewer*>(pVisual);
// Scroll
float fOffset = pScroll->GetVerticalOffset();
pScroll->ScrollToVerticalOffset(fOffset + fScrolValue);
}
}
So I tried this kind of code :
Code: Select all
void ViewModel::ScrollListBoxAnimated(const char* szComponentName, float fScrolValue)
{
Noesis::ListBox* pListBox = FindControl<Noesis::ListBox>(szComponentName);
if (pListBox != nullptr)
{
Noesis::Visual* pVisual = VisualTreeHelper::GetChild(pListBox, 0);
ScrollViewer* pScroll = static_cast<ScrollViewer*>(pVisual);
float fOffset = pScroll->GetVerticalOffset();
// Scroll animated
Ptr<PowerEase> _ease = *new PowerEase();
_ease->SetEasingMode(EasingMode_EaseOut);
_ease->SetPower(8.0f);
Ptr<DoubleAnimation> scrollanim = *new DoubleAnimation();
scrollanim->SetEasingFunction(_ease);
Nullable<float> fFrom(pScroll->GetVerticalOffset());
Nullable<float> fTo(pScroll->GetVerticalOffset() + fScrolValue);
scrollanim->SetFrom(fFrom);
scrollanim->SetTo(fTo);
scrollanim->SetDuration(*new Duration(*new Noesis::TimeSpan(2.0)));
pScroll->SetAnimation(pScroll->VerticalOffsetProperty, scrollanim);
}
}
So I also tried using a storyboard like this:
Code: Select all
void ViewModel::ScrollListBoxAnimated(const char* szComponentName, float fScrolValue)
{
Noesis::ListBox* pListBox = FindControl<Noesis::ListBox>(szComponentName);
if (pListBox != nullptr)
{
Noesis::Visual* pVisual = VisualTreeHelper::GetChild(pListBox, 0);
ScrollViewer* pScroll = static_cast<ScrollViewer*>(pVisual);
float fOffset = pScroll->GetVerticalOffset();
// Scroll animated
Ptr<PowerEase> _ease = *new PowerEase();
_ease->SetEasingMode(EasingMode_EaseOut);
_ease->SetPower(8.0f);
Ptr<DoubleAnimation> scrollanim = *new DoubleAnimation();
scrollanim->SetEasingFunction(_ease);
Nullable<float> fFrom(pScroll->GetVerticalOffset());
Nullable<float> fTo(pScroll->GetVerticalOffset() + fScrolValue);
scrollanim->SetFrom(fFrom);
scrollanim->SetTo(fTo);
scrollanim->SetDuration(*new Duration(*new Noesis::TimeSpan(2.0)));
// With sotryboard
Ptr<Storyboard> storyboard = *new Storyboard();
storyboard->GetChildren()->Add(scrollanim);
Storyboard::SetTargetName(scrollanim, pScroll->GetName());
Storyboard::SetTargetProperty(scrollanim, MakePtr<PropertyPath>(pScroll->VerticalOffsetProperty));
storyboard->Begin(pScroll);
}
}
I'm still a very beginer in Noesis / WPF and I'm surely missing something. Do you have any suggestion to make this work ?
Thanks a lot,
Frank
- andreas_sodergren
- Posts: 1
- Joined:
Re: Animate a Scrollviewer without using scrollbar
Hello,
I'm basically trying to do the same thing, and stuck.
The reason it doesn't work is because we can't animate VerticalScrollOffset because it's "Read Only"
I tried to follow these posts:
viewtopic.php?t=450
viewtopic.php?f=3&t=2066&p=11563&hilit= ... rty#p11563
https://www.noesisengine.com/docs/2.2/G ... Index.html
So i tried to create this "Extensions" thing, and i've gotten this far and now I'm not sure how to proceed.
I'm not sure if i should but when I try to NsRegisterComponent< Extensions >();
I get the following error:
Error LNK2001 unresolved external symbol "public: static class Noesis::DependencyProperty const * const Extensions::VerticalScrollProperty" (?VerticalScrollProperty@Extensions@@2PEBVDependencyProperty@Noesis@@EB)
Still working on Noesis 2.2.5.
I'm basically trying to do the same thing, and stuck.
The reason it doesn't work is because we can't animate VerticalScrollOffset because it's "Read Only"
I tried to follow these posts:
viewtopic.php?t=450
viewtopic.php?f=3&t=2066&p=11563&hilit= ... rty#p11563
https://www.noesisengine.com/docs/2.2/G ... Index.html
Code: Select all
void cContentScroller::addAnimation( float _to_scroll )
{
Noesis::DoubleAnimation* animation = new Noesis::DoubleAnimation();
animation->SetFrom( Noesis::Nullable< float >( m_scroll_viewer->GetVerticalOffset() ) );
animation->SetTo( Noesis::Nullable< float >( _to_scroll ) );
animation->SetDuration( Noesis::Duration( 1.0f ) );
Noesis::Storyboard* storyboard = new Noesis::Storyboard();
Noesis::Storyboard::SetTarget( animation, m_scroll_viewer );
Noesis::Storyboard::SetTargetProperty( animation, new Noesis::PropertyPath( Noesis::ScrollViewer::VerticalOffsetProperty ) );
storyboard->GetChildren()->Add( animation );
storyboard->Begin( m_scroll_viewer );
}
Code: Select all
class Extensions: public Noesis::BaseComponent
{
public:
static const Noesis::DependencyProperty* VerticalScrollProperty;
static float GetVerticalOffset( Noesis::DependencyObject* d )
{
return d->GetValue< float >( VerticalScrollProperty );
}
static void SetVerticalOffset( Noesis::DependencyObject* d, float offset )
{
d->SetValue< float >( VerticalScrollProperty, offset );
}
static void OnVerticalOffsetChanged( Noesis::DependencyObject* d, const Noesis::DependencyPropertyChangedEventArgs& /*e*/ )
{
Noesis::ScrollViewer* scroll = Noesis::DynamicCast< Noesis::ScrollViewer*, Noesis::DependencyObject* >( d );
if( scroll )
{
float offset = scroll->GetValue< float >( VerticalScrollProperty );
scroll->ScrollToVerticalOffset( offset );
}
}
private:
NS_IMPLEMENT_INLINE_REFLECTION( Extensions, Noesis::BaseComponent )
{
NsMeta< Noesis::TypeId >( "Extensions" );
Noesis::DependencyData* data = NsMeta< Noesis::DependencyData >( Noesis::TypeOf< SelfClass >() );
data->RegisterProperty< float >( VerticalScrollProperty, "VerticalScroll", Noesis::PropertyMetadata::Create( 0.0f, Noesis::PropertyChangedCallback( OnVerticalOffsetChanged ) ) );
}
};
I get the following error:
Error LNK2001 unresolved external symbol "public: static class Noesis::DependencyProperty const * const Extensions::VerticalScrollProperty" (?VerticalScrollProperty@Extensions@@2PEBVDependencyProperty@Noesis@@EB)
Still working on Noesis 2.2.5.
-
sfernandez
Site Admin
- Posts: 2997
- Joined:
Re: Animate a Scrollviewer without using scrollbar
ScrollViewer's HorizontalOffset and VerticalOffset properties are read-only, they can only be modified by calling ScrollViewer.ScrollToHorizontalOffset() or ScrollViewer.ScrollToVerticalOffset() functions. To do so by using animations you need attached properties that when animated they call those functions on the corresponding changed callback:
This can be used in xaml like this:
And the same translates to code:
Code: Select all
namespace Animation
{
public class ScrollViewerHelper : DependencyObject
{
public static DependencyProperty HorizontalScrollProperty = DependencyProperty.RegisterAttached(
"HorizontalScroll", typeof(float), typeof(ScrollViewerHelper),
new PropertyMetadata(0.0f, OnHorizontalScrollChanged));
public static float GetHorizontalScroll(DependencyObject d)
{
return (float)d.GetValue(HorizontalScrollProperty);
}
public static void SetHorizontalScroll(DependencyObject d, float offset)
{
d.SetValue(HorizontalScrollProperty, offset);
}
static void OnHorizontalScrollChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
ScrollViewer sv = d as ScrollViewer;
if (sv != null)
{
float offset = GetHorizontalScroll(sv);
sv.ScrollToHorizontalOffset(offset);
}
}
public static DependencyProperty VerticalScrollProperty = DependencyProperty.RegisterAttached(
"VerticalScroll", typeof(float), typeof(ScrollViewerHelper),
new PropertyMetadata(0.0f, OnVerticalScrollChanged));
public static float GetVerticalScroll(DependencyObject d)
{
return (float)d.GetValue(VerticalScrollProperty);
}
public static void SetVerticalScroll(DependencyObject d, float offset)
{
d.SetValue(VerticalScrollProperty, offset);
}
static void OnVerticalScrollChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
ScrollViewer sv = d as ScrollViewer;
if (sv != null)
{
float offset = GetVerticalScroll(sv);
sv.ScrollToVerticalOffset(offset);
}
}
}
}
Code: Select all
<Grid
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Animation">
<Grid.Resources>
<Storyboard x:Key="anim">
<DoubleAnimation Duration="0:0:2" From="0" To="100"
Storyboard.TargetName="scroll" Storyboard.TargetProperty="(local:ScrollViewerHelper.VerticalScroll)"/>
</Storyboard>
</Grid.Resources>
<ScrollViewer x:Name="scroll" Width="200" Height="200"/>
...
</Grid>
Code: Select all
DoubleAnimation a = new DoubleAnimation();
a.Duration = new TimeSpan(0, 0, 2);
a.From = 0.0f;
a.To = 100.0f;
Storyboard.SetTargetName(a, "scroll");
Storyboard.SetTargetProperty(a, Animation.ScrollViewerHelper.VerticalScrollProperty);
Storyboard s = new Storyboard();
s.Children.Add(a);
This means you forgot to add the definitions in the .cpp: https://stackoverflow.com/questions/195 ... ss-membersError LNK2001 unresolved external symbol "public: static class Noesis::DependencyProperty const * const Extensions::VerticalScrollProperty" (?VerticalScrollProperty@Extensions@@2PEBVDependencyProperty@Noesis@@EB)
Code: Select all
const Noesis::DependencyProperty* Extensions::VerticalScrollProperty;
Re: Animate a Scrollviewer without using scrollbar
Thanks a lot to you guys, I finally managed to make it work thanks to your advices.
I have just a remark:
this kind of code doesn't compile any more in the lastest version of Noesis:
I replaced it by:
It seems to work but I was wondering if this was still necessary ?
I have just a remark:
this kind of code doesn't compile any more in the lastest version of Noesis:
Code: Select all
NsMeta< Noesis::TypeId >( "Extensions" );
Code: Select all
NsMeta< Category >("Extensions");
-
sfernandez
Site Admin
- Posts: 2997
- Joined:
Re: Animate a Scrollviewer without using scrollbar
In Noesis 3.0 the type id, if you need to explicitly specify one, is set in the reflection macro itself:
The Category is not required for this to work, you can remote it if you want.
Code: Select all
NS_IMPLEMENT_REFLECTION(Extensions, "Testing.Extensions")
Who is online
Users browsing this forum: Ahrefs [Bot], Bing [Bot] and 5 guests