|
|
|
@ -7,9 +7,12 @@ |
|
|
|
namespace Perspex.Controls |
|
|
|
{ |
|
|
|
using System; |
|
|
|
using System.Linq; |
|
|
|
using System.Windows.Input; |
|
|
|
using Perspex.Input; |
|
|
|
using Perspex.Interactivity; |
|
|
|
using Perspex.Rendering; |
|
|
|
using Perspex.VisualTree; |
|
|
|
|
|
|
|
public enum ClickMode |
|
|
|
{ |
|
|
|
@ -28,6 +31,9 @@ namespace Perspex.Controls |
|
|
|
public static readonly PerspexProperty<object> CommandParameterProperty = |
|
|
|
PerspexProperty.Register<Button, object>("CommandParameter"); |
|
|
|
|
|
|
|
public static readonly PerspexProperty<bool> IsDefaultProperty = |
|
|
|
PerspexProperty.Register<Button, bool>("IsDefault"); |
|
|
|
|
|
|
|
public static readonly RoutedEvent<RoutedEventArgs> ClickEvent = |
|
|
|
RoutedEvent.Register<Button, RoutedEventArgs>("Click", RoutingStrategies.Bubble); |
|
|
|
|
|
|
|
@ -36,6 +42,7 @@ namespace Perspex.Controls |
|
|
|
FocusableProperty.OverrideDefaultValue(typeof(Button), true); |
|
|
|
ClickEvent.AddClassHandler<Button>(x => x.OnClick); |
|
|
|
CommandProperty.Changed.Subscribe(CommandChanged); |
|
|
|
IsDefaultProperty.Changed.Subscribe(IsDefaultChanged); |
|
|
|
} |
|
|
|
|
|
|
|
public event EventHandler<RoutedEventArgs> Click |
|
|
|
@ -62,6 +69,12 @@ namespace Perspex.Controls |
|
|
|
set { this.SetValue(CommandParameterProperty, value); } |
|
|
|
} |
|
|
|
|
|
|
|
public bool IsDefault |
|
|
|
{ |
|
|
|
get { return this.GetValue(IsDefaultProperty); } |
|
|
|
set { this.SetValue(IsDefaultProperty, value); } |
|
|
|
} |
|
|
|
|
|
|
|
protected override Size MeasureOverride(Size availableSize) |
|
|
|
{ |
|
|
|
return base.MeasureOverride(availableSize); |
|
|
|
@ -72,6 +85,34 @@ namespace Perspex.Controls |
|
|
|
return base.ArrangeOverride(finalSize); |
|
|
|
} |
|
|
|
|
|
|
|
protected override void OnAttachedToVisualTree(IRenderRoot root) |
|
|
|
{ |
|
|
|
base.OnAttachedToVisualTree(root); |
|
|
|
|
|
|
|
if (this.IsDefault) |
|
|
|
{ |
|
|
|
var inputElement = root as IInputElement; |
|
|
|
|
|
|
|
if (inputElement != null) |
|
|
|
{ |
|
|
|
this.ListenForDefault(inputElement); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
protected override void OnDetachedFromVisualTree(IRenderRoot oldRoot) |
|
|
|
{ |
|
|
|
if (this.IsDefault) |
|
|
|
{ |
|
|
|
var inputElement = oldRoot as IInputElement; |
|
|
|
|
|
|
|
if (inputElement != null) |
|
|
|
{ |
|
|
|
this.StopListeningForDefault(inputElement); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
protected virtual void OnClick(RoutedEventArgs e) |
|
|
|
{ |
|
|
|
if (this.Command != null) |
|
|
|
@ -131,6 +172,26 @@ namespace Perspex.Controls |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private static void IsDefaultChanged(PerspexPropertyChangedEventArgs e) |
|
|
|
{ |
|
|
|
var button = e.Sender as Button; |
|
|
|
var isDefault = (bool)e.NewValue; |
|
|
|
var root = button.GetSelfAndVisualAncestors().OfType<IRenderRoot>().FirstOrDefault(); |
|
|
|
var inputElement = root as IInputElement; |
|
|
|
|
|
|
|
if (inputElement != null) |
|
|
|
{ |
|
|
|
if (isDefault) |
|
|
|
{ |
|
|
|
button.ListenForDefault(inputElement); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
button.StopListeningForDefault(inputElement); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private void CanExecuteChanged(object sender, EventArgs e) |
|
|
|
{ |
|
|
|
// HACK: Just set the IsEnabled property for the moment. This needs to be changed to
|
|
|
|
@ -138,6 +199,16 @@ namespace Perspex.Controls |
|
|
|
this.IsEnabled = this.Command == null || this.Command.CanExecute(this.CommandParameter); |
|
|
|
} |
|
|
|
|
|
|
|
private void ListenForDefault(IInputElement root) |
|
|
|
{ |
|
|
|
root.AddHandler(InputElement.KeyDownEvent, this.RootKeyDown, RoutingStrategies.Tunnel); |
|
|
|
} |
|
|
|
|
|
|
|
private void StopListeningForDefault(IInputElement root) |
|
|
|
{ |
|
|
|
root.RemoveHandler(InputElement.KeyDownEvent, this.RootKeyDown); |
|
|
|
} |
|
|
|
|
|
|
|
private void RaiseClickEvent() |
|
|
|
{ |
|
|
|
RoutedEventArgs click = new RoutedEventArgs |
|
|
|
@ -147,5 +218,13 @@ namespace Perspex.Controls |
|
|
|
|
|
|
|
this.RaiseEvent(click); |
|
|
|
} |
|
|
|
|
|
|
|
private void RootKeyDown(object sender, KeyEventArgs e) |
|
|
|
{ |
|
|
|
if (e.Key == Key.Enter && this.IsVisible && this.IsEnabled) |
|
|
|
{ |
|
|
|
this.RaiseClickEvent(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|