Skip to content

Instantly share code, notes, and snippets.

@cairey
Created August 26, 2011 10:56
Show Gist options
  • Save cairey/1173189 to your computer and use it in GitHub Desktop.
Save cairey/1173189 to your computer and use it in GitHub Desktop.
Just like Hover Intent in JQuery, this is Hover Intent Behavior for Silverlight. See "Read Me" below.
public class MouseEnterIntent
{
public static readonly DependencyProperty CommandProperty =
DependencyProperty.RegisterAttached("Command", typeof(ICommand), typeof(MouseEnterIntent), new PropertyMetadata(OnSetCommandCallback));
public static readonly DependencyProperty CommandParameterProperty =
DependencyProperty.RegisterAttached("CommandParameter", typeof(object), typeof(MouseEnterIntent), new PropertyMetadata(OnSetCommandParameterCallback));
public static readonly DependencyProperty MouseEnterIntentCommandBehaviorProperty =
DependencyProperty.RegisterAttached("HoverIntentCommandBehavior", typeof(MouseEnterIntentCommandBehavior), typeof(MouseEnterIntent), null);
public static readonly DependencyProperty DueTimeProperty =
DependencyProperty.RegisterAttached("DueTime", typeof(object), typeof(MouseEnterIntent), new PropertyMetadata(OnSetMouseEnterIntentDueTimeCallback));
public static ICommand GetCommand(DependencyObject obj)
{
return (ICommand)obj.GetValue(CommandProperty);
}
public static void SetCommand(DependencyObject obj, ICommand value)
{
obj.SetValue(CommandProperty, value);
}
public static object GetCommandParameter(DependencyObject obj)
{
return obj.GetValue(CommandParameterProperty);
}
public static void SetCommandParameter(DependencyObject obj, object parameter)
{
obj.SetValue(CommandParameterProperty, parameter);
}
public static MouseEnterIntentCommandBehavior GetMouseIntentCommandBehavior(DependencyObject obj)
{
return (MouseEnterIntentCommandBehavior)obj.GetValue(MouseEnterIntentCommandBehaviorProperty);
}
public static void SetHoverIntentCommandBehavior(DependencyObject obj, MouseEnterIntentCommandBehavior value)
{
obj.SetValue(MouseEnterIntentCommandBehaviorProperty, value);
}
public static object GetDueTime(DependencyObject obj)
{
return obj.GetValue(DueTimeProperty);
}
public static void SetDueTime(DependencyObject obj, object parameter)
{
obj.SetValue(DueTimeProperty, parameter);
}
private static void OnSetCommandCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
Control element = dependencyObject as Control;
if (element != null)
{
MouseEnterIntentCommandBehavior behavior = GetOrCreateBehavior(element);
behavior.Command = e.NewValue as ICommand;
}
}
private static void OnSetCommandParameterCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
Control element = dependencyObject as Control;
if (element != null)
{
MouseEnterIntentCommandBehavior behavior = GetOrCreateBehavior(element);
behavior.CommandParameter = e.NewValue;
}
}
private static void OnSetMouseEnterIntentDueTimeCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
Control element = dependencyObject as Control;
if (element != null)
{
MouseEnterIntentCommandBehavior behavior = GetOrCreateBehavior(element);
if (e.NewValue is TimeSpan)
behavior.DueTime = (TimeSpan)e.NewValue;
else
behavior.DueTime = TimeSpan.FromMilliseconds(Double.Parse(e.NewValue.ToString()));
}
}
private static MouseEnterIntentCommandBehavior GetOrCreateBehavior(Control element)
{
MouseEnterIntentCommandBehavior behavior = element.GetValue(MouseEnterIntentCommandBehaviorProperty) as MouseEnterIntentCommandBehavior;
if (behavior == null)
{
behavior = new MouseEnterIntentCommandBehavior(element);
element.SetValue(MouseEnterIntentCommandBehaviorProperty, behavior);
}
return behavior;
}
}
public class MouseEnterIntentCommandBehavior : CommandBehaviorBase
{
private readonly Control _element;
private TimeSpan _dueTime;
private IDisposable _hoverEvent;
public MouseEnterIntentCommandBehavior(Control element)
: base(element)
{
_element = element;
_dueTime = TimeSpan.FromMilliseconds(300);
Initialise();
}
private void Initialise()
{
if (_hoverEvent != null) _hoverEvent.Dispose();
var mouseLeave = Observable.FromEvent(_element, "MouseLeave");
_hoverEvent = Observable.FromEvent(_element, "MouseEnter")
.Intent(mouseLeave, _dueTime)
.Subscribe(x => ExecuteCommand());
}
public TimeSpan DueTime
{
get { return _dueTime; }
set
{
if (_dueTime == value) return;
_dueTime = value;
Initialise();
}
}
}
public static class ObservableExtentions
{
public static IObservable<T> Intent<T, T2>(this IObservable<T> source, IObservable<T2> takeUntil, TimeSpan dueTime)
{
return source.Throttle(dueTime).TakeUntil(takeUntil).Repeat();
}
}
Dependency on the Silverlight Reactive Extensions.
In MVVM you will have a view model on which you can bind to a command. DueTime can be binded from the View Model as a TimeSpan, String or Int or specified in XAML like below. Enter a value in milliseconds.
Use "Command" to bind to your view model command
Use "DueTime" to bind to your view model property or enter direct in XAML. This specifies the time in which the mouse needs to be hovered on the item for before triggering the command. Enter time in milliseconds.
You can then bind in the XAML like so:
Button x:Name="Eyecon" commands:MouseEnterIntent.Command="{Binding Open}" commands:MouseEnterIntent.DueTime="50"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment