Skip to content

657 keybinding issue when attaching it to windows with commands with canexecute methods #971

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/Caliburn.Micro.Platform/Action.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ namespace Caliburn.Micro
using System.Reflection;
#elif WinUI3
using System.Linq;
using Microsoft.UI.Xaml;
using System.Reflection;
using Microsoft.UI.Xaml;
#elif XFORMS
using UIElement = global::Xamarin.Forms.Element;
using FrameworkElement = global::Xamarin.Forms.VisualElement;
Expand Down Expand Up @@ -174,7 +174,8 @@ public static void Invoke(object target, string methodName, DependencyObject vie
Message = message,
View = view,
Source = source,
EventArgs = eventArgs
EventArgs = eventArgs,
SkipAvailabilityResolution = Message.GetSkipAvailabilityResolution(view)
};

if (parameters != null)
Expand Down
37 changes: 28 additions & 9 deletions src/Caliburn.Micro.Platform/ActionExecutionContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ namespace Caliburn.Micro
/// <summary>
/// The context used during the execution of an Action or its guard.
/// </summary>
public class ActionExecutionContext : IDisposable {
public class ActionExecutionContext : IDisposable
{
private WeakReference _message;
private WeakReference _source;
private WeakReference _target;
Expand All @@ -51,39 +52,53 @@ public class ActionExecutionContext : IDisposable {
/// </summary>
public object EventArgs;

/// <summary>
/// Gets or sets a value indicating whether to skip availability resolution.
/// </summary>
public bool SkipAvailabilityResolution
{
get => _skipAvailabilityResolution;
set => _skipAvailabilityResolution = value;
}

/// <summary>
/// The actual method info to be invoked.
/// </summary>
public MethodInfo Method;
private bool _skipAvailabilityResolution;

/// <summary>
/// The message being executed.
/// </summary>
public ActionMessage Message {
public ActionMessage Message
{
get { return _message == null ? null : _message.Target as ActionMessage; }
set { _message = new WeakReference(value); }
}

/// <summary>
/// The source from which the message originates.
/// </summary>
public FrameworkElement Source {
public FrameworkElement Source
{
get { return _source == null ? null : _source.Target as FrameworkElement; }
set { _source = new WeakReference(value); }
}

/// <summary>
/// The instance on which the action is invoked.
/// </summary>
public object Target {
public object Target
{
get { return _target == null ? null : _target.Target; }
set { _target = new WeakReference(value); }
}

/// <summary>
/// The view associated with the target.
/// </summary>
public DependencyObject View {
public DependencyObject View
{
get { return _view == null ? null : _view.Target as DependencyObject; }
set { _view = new WeakReference(value); }
}
Expand All @@ -93,8 +108,10 @@ public DependencyObject View {
/// </summary>
/// <param name="key">The data key.</param>
/// <returns>Custom data associated with the context.</returns>
public object this[string key] {
get {
public object this[string key]
{
get
{
if (_values == null)
_values = new Dictionary<string, object>();

Expand All @@ -103,7 +120,8 @@ public object this[string key] {

return result;
}
set {
set
{
if (_values == null)
_values = new Dictionary<string, object>();

Expand All @@ -114,7 +132,8 @@ public object this[string key] {
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose() {
public void Dispose()
{
Disposing(this, System.EventArgs.Empty);
}

Expand Down
30 changes: 25 additions & 5 deletions src/Caliburn.Micro.Platform/ActionMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@
set { SetValue(MethodNameProperty, value); }
}

public bool SkipAvailabilityResolution { get; set; }

Check warning on line 164 in src/Caliburn.Micro.Platform/ActionMessage.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'ActionMessage.SkipAvailabilityResolution'

Check warning on line 164 in src/Caliburn.Micro.Platform/ActionMessage.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'ActionMessage.SkipAvailabilityResolution'

Check warning on line 164 in src/Caliburn.Micro.Platform/ActionMessage.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'ActionMessage.SkipAvailabilityResolution'

Check warning on line 164 in src/Caliburn.Micro.Platform/ActionMessage.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'ActionMessage.SkipAvailabilityResolution'

Check warning on line 164 in src/Caliburn.Micro.Platform/ActionMessage.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'ActionMessage.SkipAvailabilityResolution'

Check warning on line 164 in src/Caliburn.Micro.Platform/ActionMessage.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'ActionMessage.SkipAvailabilityResolution'

Check warning on line 164 in src/Caliburn.Micro.Platform/ActionMessage.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'ActionMessage.SkipAvailabilityResolution'

Check warning on line 164 in src/Caliburn.Micro.Platform/ActionMessage.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'ActionMessage.SkipAvailabilityResolution'

/// <summary>
/// Gets the parameters to pass as part of the method invocation.
/// </summary>
Expand Down Expand Up @@ -315,8 +317,9 @@
Log.Info($"Binding {binding.Source}");

#elif (NET || CAL_NETCORE) && !WinUI3 && !WINDOWS_UWP
var binding = new Binding {
Path = new PropertyPath(Message.HandlerProperty),
var binding = new Binding
{
Path = new PropertyPath(Message.HandlerProperty),
Source = currentElement
};
#elif WINDOWS_UWP || WinUI3
Expand Down Expand Up @@ -365,7 +368,8 @@
_context = new ActionExecutionContext
{
Message = this,
Source = AssociatedObject
Source = AssociatedObject,
SkipAvailabilityResolution = SkipAvailabilityResolution
};

PrepareContext(_context);
Expand Down Expand Up @@ -528,15 +532,30 @@
Log.Info($"context.CanExecute is null {context.CanExecute == null} ");
if (context.CanExecute != null)
{
Log.Info("HERE");
Log.Info($"ApplyAvailabilityEffect CanExecute {context.Method.Name}");
source.IsEnabled = context.CanExecute();
}
#else
if (!hasBinding && context.CanExecute != null)
{
Log.Info($"ApplyAvailabilityEffect CanExecute {context.CanExecute()} - {context.Method.Name}");
source.IsEnabled = context.CanExecute();
if (!context.SkipAvailabilityResolution)
{
Log.Info($"ApplyAvailabilityEffect CanExecute {context.CanExecute()} - {context.Method.Name} - {source.Name}");
source.IsEnabled = context.CanExecute();
}
else
{
Log.Info("Skipping IsEnabled source because source Name is not set");
}
if (!source.IsEnabled)
{
Log.Info($"Disabled {source.Name}");
}
else
{
Log.Info($"Enabled {source.Name}");
}
}
#endif
Log.Info($"ApplyAvailabilityEffect source enabled {source.IsEnabled}");
Expand Down Expand Up @@ -615,6 +634,7 @@
}
}
#else

if (source != null && source.DataContext != null)
{
var target = source.DataContext;
Expand Down
46 changes: 44 additions & 2 deletions src/Caliburn.Micro.Platform/Message.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ namespace Caliburn.Micro
/// </summary>
public static class Message
{
internal const string Skip_Availability_Resolution = "SkipAvailabilityResolution";
internal static readonly DependencyProperty HandlerProperty =
#if AVALONIA
AvaloniaProperty.RegisterAttached<AvaloniaObject, object>("Handler", typeof(Message));
Expand Down Expand Up @@ -107,11 +108,28 @@ public static object GetHandler(DependencyObject d)
"Attach",
typeof(string),
typeof(Message),
null,
null,
OnAttachChanged
);
#endif

/// <summary>
/// A property definition representing whether should check if the function can be executed
/// </summary>
public static readonly DependencyProperty SkipAvailabilityResolutionProperty =
#if AVALONIA
AvaloniaProperty.RegisterAttached<AvaloniaObject, string>(Skip_Availability_Resolution, typeof(Message));
#else
DependencyPropertyHelper.RegisterAttached(
Skip_Availability_Resolution,
typeof(string),
typeof(Message),
null,
OnAttachChanged
);
#endif


#if AVALONIA
static Message()
{
Expand All @@ -138,6 +156,29 @@ public static string GetAttach(DependencyObject d)
return d.GetValue(AttachProperty) as string;
}

/// <summary>
/// Sets the attached triggers and messages.
/// </summary>
/// <param name="d"> The element to attach to. </param>
/// <param name="skip"> The parsable attachment text. </param>
public static void SetSkipAvailabilityResolution(DependencyObject d, string skip)
{
d.SetValue(SkipAvailabilityResolutionProperty, skip);
}

/// <summary>
/// Gets the attached triggers and messages.
/// </summary>
/// <param name="d"> The element that was attached to. </param>
/// <returns> The parsable attachment text. </returns>
public static bool GetSkipAvailabilityResolution(DependencyObject d)
{
var value = d.GetValue(SkipAvailabilityResolutionProperty) as string;
if (!bool.TryParse(value, out bool result))
result = false;
return result;
}

static void OnAttachChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (object.ReferenceEquals(e.NewValue, e.OldValue))
Expand All @@ -162,7 +203,8 @@ static void OnAttachChanged(DependencyObject d, DependencyPropertyChangedEventAr

var allTriggers = visualElement != null ? visualElement.Triggers : new List<TriggerBase>();

if (messageTriggers != null) {
if (messageTriggers != null)
{
messageTriggers.Apply(x => allTriggers.Remove(x));
}

Expand Down
6 changes: 3 additions & 3 deletions src/Caliburn.Micro.Platform/Parser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public static class Parser
/// <param name="text">The message text.</param>
/// <returns>The triggers parsed from the text.</returns>
#if AVALONIA
public static IEnumerable<EventTrigger> Parse(DependencyObject target, string text)
public static IEnumerable<EventTrigger> Parse(DependencyObject target, string text)
#else
public static IEnumerable<TriggerBase> Parse(DependencyObject target, string text)
#endif
Expand Down Expand Up @@ -232,7 +232,7 @@ private static void AddActionToTrigger(DependencyObject target, TriggerAction me
/// </summary>
/// <remarks>The parameters passed to the method are the the target of the trigger and string representing the trigger.</remarks>
public static Func<DependencyObject, string, EventTrigger> CreateTrigger = (target, triggerText) =>

#else
/// <summary>
/// The function used to generate a trigger.
Expand Down Expand Up @@ -302,7 +302,7 @@ public static TriggerAction CreateMessage(DependencyObject target, string messag
/// </summary>
public static Func<DependencyObject, string, TriggerAction> InterpretMessageText = (target, text) =>
{
return new ActionMessage { MethodName = Regex.Replace(text, "^Action", string.Empty).Trim() };
return new ActionMessage { MethodName = Regex.Replace(text, "^Action", string.Empty).Trim(), SkipAvailabilityResolution = Message.GetSkipAvailabilityResolution(target) };
};

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
/// <value>The name of the method.</value>
public string MethodName { get; set; }

public bool SkipAvailabilityResolution { get; set; }

Check warning on line 52 in src/Caliburn.Micro.Platform/Platforms/Maui/ActionMessage.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'ActionMessage.SkipAvailabilityResolution'

Check warning on line 52 in src/Caliburn.Micro.Platform/Platforms/Maui/ActionMessage.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'ActionMessage.SkipAvailabilityResolution'

Check warning on line 52 in src/Caliburn.Micro.Platform/Platforms/Maui/ActionMessage.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'ActionMessage.SkipAvailabilityResolution'

Check warning on line 52 in src/Caliburn.Micro.Platform/Platforms/Maui/ActionMessage.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'ActionMessage.SkipAvailabilityResolution'

Check warning on line 52 in src/Caliburn.Micro.Platform/Platforms/Maui/ActionMessage.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'ActionMessage.SkipAvailabilityResolution'

Check warning on line 52 in src/Caliburn.Micro.Platform/Platforms/Maui/ActionMessage.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'ActionMessage.SkipAvailabilityResolution'
/// <summary>
/// The handler for the action.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
/// <remarks>True by default.</remarks>
public static bool ThrowsExceptions = true;

public bool SkipAvailabilityResolution { get; set; } = false;

Check warning on line 35 in src/Caliburn.Micro.Platform/Platforms/Xamarin.Forms/ActionMessage.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'ActionMessage.SkipAvailabilityResolution'

Check warning on line 35 in src/Caliburn.Micro.Platform/Platforms/Xamarin.Forms/ActionMessage.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'ActionMessage.SkipAvailabilityResolution'
/// <summary>
/// Creates an instance of <see cref="ActionMessage"/>.
/// </summary>
Expand Down
Loading