Match selectors from left-to-right, as before we were checking things like property equality (and creating a `PropertyEqualsActivator`) before checking that the control is of the correct type. Also hopefully makes the selector matching logic more readable.
- Don't use Rx in the styling system. Instead introduces `IStyleActivator` which is like an `IObservable<bool>`-lite in order to cut down on allocations.
- #nullable enable on touched files
- When detaching set `Parent` to `null` before raising the `DetachedFromLogicalTree` event
- To do this, we need to store the logical root in the control so that e.g. a child control can be detached in a `DetachedFromLogicalTree` handler
- Add `Source` and `Parent` properties to `LogicalTreeAttachmentEventArgs` to give more context on what caused the attachment/detachment
When a `TemplateBinding` is used as a `Setter.Value`, then we need to make sure we don't use the `TemplateBinding` itself as the binding because this can cause a memory leak.
Replace `IRequiresTemplateInSetter` with `ISetterValue` which can be used to require a template in the setter for `Control` and can also be used to notify `TemplateBinding` that it's in a setter and so should always clone itself.
Fixes#2420
This is a relic from when we were targeting a PCL profile that didn't have `System.ComponentModel.ISupportInitialize`. Now that we have that, use it instead.
Previously `PropertyChanged` was raised on the child before the parent because the inherited value change was being notified by listening to the parent `PropertyChanged` event, and this event handler was added first.
Added an `InheritablePropertyChanged` event which will be called only after all other property changed events have been raised and only for inheritable properties.
A lot of time was being spent calling `Attach` on styles that will never match a control. On the first pass, cache the styles that can match a particular control type and use this cache to bypass styles that will never match on subsequent passes.
Previously it wasn't clear which constructor on `InstancedBinding` must be called for a particular binding mode. Refactored the constructors:
- We now have a single public ctor which takes an `ISubject`, as a subject can be used for all binding modes.
- Instanced bindings with other sources such as single values and `IObservables` are now constructed via static methods which only allow the correct sources for that binding mode