-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
CommandParameter is null when call CanExecute method at first time #316
Comments
I'm having uncomfortable flashbacks to when I first learned of this I'm not sure anything can be done about this. XAML properties are assigned sequentially, and I doubt that's negotiable. This would probably require some kind of hack in the XAML reader. |
@brandonhood, or the button could just defer the call between |
In my opinion, the XAML equals to the codes: var button = new Button
{
Content = "Test",
Command = ...
CommandParameter = ...
}; and the CanExecute method will be called by some methods such as Load ... |
The .NET framework version of the xaml parser honours the ISupportInitialize interface (which is implemented by FrameworkElement), so its actually more like this: var button = new Button();
((ISupportInitialize)button).BeginInit();
button.Content = "Test";
button.Command = ...
button.CommandParameter = ...
((ISupportInitialize)button).EndInit(); |
This comment has been minimized.
This comment has been minimized.
I agree that this behavior is incorrect. I think something like this should be pretty straightforward to do. |
This issue been around for a while. The easiest fix for now is to change the order so that CommandParameter appears before Command but order should not matter. |
…after initialization. Issue dotnet#316 Revert changes to Hyperlink.cs
I would like to propose a solution for the Button and MenuItem cases mentioned in the linked Stack Overflow question above. Looking at stack trace that leads to the bug for the Button case StackTrace leading to ICommand.CanExecute Bug.txt we see that the error occurs in the The idea is to delay the execution of this method until the WPF elements are initialized. See the above linked commit 0c6b967 for the details. |
The attached test project can be used to verify the proposed solution. |
@vatsan-madhavan not sure whats left to discuss, I think everyone agreed that its a bug. My concern about having to duplicate the code has been addressed by placing the code in a central helper method so it doesn't have to be placed in every site that has commands, I don't think the change is unreasonable. As far as behavioral changes is happening, this just suppresses a call with incomplete arguments, the next query of CanExecute will have the correct parameters, most callers are going to ignore the first incomplete call anyways. I suggest to reconsider the PR for post 3.0 RTM when behavioral changes are allowed again. |
I think a better approach would be to first fix the behaviour of CommandParameter so that CanExecute is called whenever the parameter is changed. That should also solve the problems described here. Even if CanExecute would be called twice if parameters are in "wrong" order the end result would be the expected behaviour. The behavior was fixed in silverlight but did never make it back to wpf (for backwards compatibility reasons i guess) so would really like to see it fixed for 3.1 so that CommanManager needs not be used for simple commands |
I agree with @Daniel-Svensson. There is no guarantee a caller will use the @vflame I believe the XAML standard specifies the order actually matters. |
@miloush this issue is about XAML attribute order and the WPF implementation of the XAML loader does use ISupportInitialize (the interface is implemented on FrameworkElement base class and will always be used when loading from XAML). So I don't think your argument against using ISupportInitialize is valid. That said I don't mind the alternative solution suggested by @Daniel-Svensson |
@weltkante XAML loader is not the only way how an element can be constructed. The problem with moving to Either way, I think the compatibility favours Daniel's solution (I actually consider it a bug that changing command parameter does not update the CanExecute state). You will still get the first call with null parameter, and the handler is expected to be called multiple times (not deterministically), so adding more calls shouldn't be breaking. |
This is truely ridiculous. As @Daniel-Svensson said, the actual issue here is that This causes issues beyond this one, for example when using This affects WPF for .NET Framework as well, not only the new .NET Core variant. |
Hopefully this link will help Thanks "Ed Downs" public static class ButtonHelper
{
public static DependencyProperty CommandParameterProperty = DependencyProperty.RegisterAttached(
"CommandParameter",
typeof(object),
typeof(ButtonHelper),
new PropertyMetadata(CommandParameter_Changed));
private static void CommandParameter_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var target = d as ButtonBase;
if (target == null)
return;
target.CommandParameter = e.NewValue;
var temp = target.Command;
// Have to set it to null first or CanExecute won't be called.
target.Command = null;
target.Command = temp;
}
public static object GetCommandParameter(ButtonBase target)
{
return target.GetValue(CommandParameterProperty);
}
public static void SetCommandParameter(ButtonBase target, object value)
{
target.SetValue(CommandParameterProperty, value);
}
} |
Can we have a fix for this broken behavior? I remember running into this bug for over 8 years now and having to use a workaround. Putting There should be a switch or something to apply this bug fix. Surely there will be workarounds from the last 14 years that will break. |
Microsoft has shifted its focus to WinUI 3, give it up, rubbish WPF. |
Abandoned UI frameworks I am aware of since the introduction of WPF:
If you believe that WinUI 3 will stay alive for more than 2-3 years, then you haven't been paying attention. |
If WinUI 3 focus on Win32 App, that will be difference. |
Got same issue today, .NET 6 WPF. |
Stop expecting any functional updates, improvements, and fixes in WPF. The vast majority of updates are xaml-related, which is likely just incidental to Microsoft updating other UI frameworks that use xaml. |
@heku - This has been fixed in RC1 release. You may try it out. |
@DaveInCaz - We haven't yet. But we'll be publishing them soon. |
@pchaurasia14 it looks like this was the change you're referring to, is that right? I could see that in the list of commits for the RC1 release. |
@DaveInCaz - Yup, that's the one I think it is. |
@pchaurasia14 what does it mean that .NET 6.0 RC1 was released in 2021, but this commit was done only in July 2022? |
@DaveInCaz - I meant, .NET 7 RC1. |
Closing as the PR is already merged for this. |
windows 10
)Problem description:
I have a TestCommand as below:
and then I use it in a xaml file:
Actual behavior:
At first time the CanExecute method is called, the parameter's value is null。
If I change the XAML property's order as below, the parameter's value is abcdef (that's ok):
Expected behavior:
The parameter's value is not null at each time, regardless of the XAML order
Minimal repro:
The text was updated successfully, but these errors were encountered: