-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Introduce BehaviorBase and let FadeHeaderBehavior derive from this base #1010
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
Conversation
|
@GeertvanHorrik, It will cover your contributions to all Microsoft-managed open source projects. |
|
I've created the Please review the code. If it looks ok, I'll fix the other |
|
@GeertvanHorrik, thanks for signing the contribution license agreement. We will now validate the agreement and then the pull request. |
|
It was so little work that I've done the other 2 behaviors as well. Ready for review & merge if all is good. |
lukasf
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I have found a few issues, please check my remarks...
|
|
||
| private void HandleAttach() | ||
| { | ||
| if (_isAttached || _isAttached) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this is supposed to be _isAttaching || _isAttached?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, will fix.
| // Confirm that Windows.UI.Xaml.Hosting.ElementCompositionPreview is available (Windows 10 10586 or later). | ||
| if (!ApiInformation.IsMethodPresent("Windows.UI.Xaml.Hosting.ElementCompositionPreview", nameof(ElementCompositionPreview.GetScrollViewerManipulationPropertySet))) | ||
| { | ||
| return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be better to return "true" here, otherwise the method will be called again and again on each SizeChanged.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, will fix.
| if (!ApiInformation.IsMethodPresent("Windows.UI.Xaml.Hosting.ElementCompositionPreview", nameof(ElementCompositionPreview.GetScrollViewerManipulationPropertySet))) | ||
| { | ||
| return; | ||
| return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be better to return "true" here, otherwise the method will be called again and again on each SizeChanged.
| if (!ApiInformation.IsMethodPresent("Windows.UI.Xaml.Hosting.ElementCompositionPreview", nameof(ElementCompositionPreview.GetScrollViewerManipulationPropertySet))) | ||
| { | ||
| return; | ||
| return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be better to return "true" here, otherwise the method will be called again and again on each SizeChanged.
- Don't allow retries of behavior subscription when the composition types are not present
|
@lukasf Thanks for the review, all should be fixed. |
|
@GeertvanHorrik Thanks, looks all good now! |
|
Do you think we should change this file to inherit from your behaviorbase? cc @shenchauhan |
|
I don't think it should be added to the chain of derived types for Composition Behavior animations that we have. I think I need more convincing that this is the right approach for it. I need help in understanding how this is going to stop multiple instances? From what I can tell there is nothing stopping me from creating multiple instances. The BehaviourBase also takes type T which could be anything. However, the code looks for FrameworkElement when checking the AssociatedObject. Why not change T to FrameworkElement? |
|
I kept that one intact because I didn't want this change to become too big or impact too many other behaviors. It doesn't necessarily prevent you from creating multiple behavior instance (that should still be possible since it's a valid use-case). However, it does prevent the behavior from accidentally assign the animation multiple times (for example on the I've added a type constraint |
|
I agree with @shenchauhan that the type constraint should be FrameworkElement. The whole point of the new BehaviorBase is to auto retry the attachment on Loaded and on SizeChanged. Both are only supported on FrameworkElement, so using the BehaviorBase on UIElement will not give any benefits over Behavior. But for all FrameworkElement targets, the base class makes a lot of sense. Probably all behaviors will need to wait at least for Loaded to get into action. So I am with @deltakosh that the CompositionBehaviorBase should be converted, then we have all Behaviors on the new base class. Plus, the type constraint for CompositionBehaviorBase should be changed to FrameworkElement as well. It does not work with UIElements, because it waits for Loaded to start the animation, so the type constraint was wrong to begin with. |
|
@lukasf I don't agree. It also prevents a duplicate attach call while the behavior is already attaching. So when I call the |
|
@GeertvanHorrik I am pretty sure that the Behavior base class makes sure that Attach is only called once, that is when the behaviors are assigned to the target Behaviors collection (and before the element is loaded into the UI tree). So my assumption is that the duplicate attach you are seeing is rather an internal issue of the BehaviorBase, where HandleAttach is called not only on Attach, but also on Loaded and SizeChanged. Probably either Loaded or SizeChaged is fired while you are attaching, so you get a second HandleAttach call. Have you checked in the debugger where the calls originate from? |
|
@lukasf It happened before I introduced the |
|
As you can see, setting the |
|
Okay, so as I assumed, the second call does not come from Behavior.Attach but from a custom event handler. My point was that Behavior.Attach will never get called multiple times. It is the specific behavior implementation which causes this behavior. But I see now that a similar situation might occur with behaviors for UIElement, so using BehaviorBase might help even for UIElement. As a side note, I am not sure if it is such a good idea to change the HeaderElement property on attach, as it is done in all Header Behaviors right now. HeaderElement is a public setter property, it might be data bound (only currently evaluating to zero). By assigning a new value, an existing binding assigned by user/dev would be removed/overridden. I'd think that controls usually should avoid changing public setter properties, unless it is required for the control to work (e.g. property is the "output" of the control). Would it perhaps be better to store the effectively used header (either from HeaderElement or implicit from ListViewBase) in a private field, just like scroll viewer? |
|
Hello I would like to close on this one soon as we plan to code freeze on 3/21 |
|
You can ignore my last comment then, it's not so important anyways. I'd still propose to also convert the last behavior to BehaviorBase, so we have them all on the same base class... |
|
I agree |
|
Just ping me if you want me to change the other behaviors as well. |
|
Ping @shenchauhan who tought they must provide default implementation (even empty) instead of abstract method so that inheriting from it is straightforward |
|
@GeertvanHorrik I'm ok with adding it to the other behaviours for consistency purposes and as long as those abstract methods do something meaningful in the other behaviours too. |
|
@GeertvanHorrik Do you mind to update all behaviors? I just would like to mark some abstract methods as virtual (and empty) so child classes won't be force to provide empty methods |
|
I'll update all behaviors and make abstract methods virtual instead. |
|
Lovely! |
|
|
I've noticed that Detach() was biting the IBehavior.Detach() method so have renamed these to Initialize and Uninitialize. If there are issues with this, ping me and I will change that. |
|
Done, pushed the changes. Also fixed all warnings. |
|
@shenchauhan do you mind reviewing the changes? |
|
reviewing now, just pulling PR. Should have an answer by EOD. |
shenchauhan
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please try running the Sample app. It crashes for me when I try to view the animation behaviors. InitializeComponent fails. Failed to assign to property 'Microsoft.Toolkit.Uwp.UI.Animations.Behaviors.CompositionBehaviorBase`1<Windows.UI.Xaml.UIElement>.AutomaticallyStart'. [Line: 19 Position: 35]'
|
Investigating now. |
|
I forgot the change the owner type when making the CompositionBehaviorBase generic. Fix incoming. |


See #1008