0

I am trying to understand how notification works for Attached Properties in WPF.

For example, consider the ScrollViewer.CanContentScrollProperty property.

Suppose we have the following ListBox

<ListBox x:Name="MainListBox"
         Grid.Row="1"
         ScrollViewer.CanContentScroll="False">
  <ListBox.ItemTemplate>
    <DataTemplate>
      <StackPanel Orientation="Horizontal">
        <TextBlock Text="{Binding CustomerID}"/>
      </StackPanel>
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>

And in the Window code we will write the following code

private void Button_Click_1(object sender, RoutedEventArgs e)
{
  MainListBox.SetValue(ScrollViewer.CanContentScrollProperty, true);
}

After executing Button_Click_1, the ListBox will automatically switch to CanContentScroll = true mode, but it is not clear how ScrollViewer receives information that the values of the connected property have been changed. It can be assumed that through the function FrameworkPropertyMetadata (PropertyChangedCallback propertyChangedCallback) , but the fact is that the property ScrollViewer.CanContentScrollProperty does not define a PropertyChanged function.

Here is the declaration code for this property.

      public class ScrollViewer : ContentControl
...
        public static readonly DependencyProperty CanContentScrollProperty = DependencyProperty.RegisterAttached(
nameof (CanContentScroll), typeof (bool), typeof (ScrollViewer), 
(PropertyMetadata) new FrameworkPropertyMetadata(BooleanBoxes.FalseBox));

It can be seen that the function for the change is not registered.

How then does ScrollViewer know that a ScrollViewer.CanContentScrollProperty property has been changed?

Luke
  • 11,211
  • 2
  • 27
  • 38
DmitryB
  • 455
  • 1
  • 5
  • 18
  • This question is way too broad. You are basically asking for a discussion of the WPF dependency property system implementation. Stack Overflow isn't the appropriate place for those kinds of detailed "whitepaper" like explanations. That said, the short version is: dependency properties, whether attached or not, don't raise `INotifyPropertyChanged` at all. Notifications and property updates are handled entirely internally to the dependency property system. – Peter Duniho May 11 '20 at 02:18
  • @PeterDuniho, the question is specifically about one attached DP. it doesn't ask for discussion or detailed explanation. also `INotifyPropertyChanged` is not mentioned in the question - only in your comment. That said, the short version is: the question is not too broad and it is appropriate and answerable – ASh May 17 '20 at 17:12
  • @ASh: _"it doesn't ask for discussion or detailed explanation"_ -- of course it does: "I am trying to understand how notification works for Attached Properties in WPF". The author did not limit the question to _an_ attached property, but is asking for how they work in general. _"INotifyPropertyChanged is not mentioned in the question"_ -- of course it is: "the fact is that the property ScrollViewer.CanContentScrollProperty does not define a PropertyChanged function". The author is clearly asking why this works in spite of there not being a `PropertyChanged` event, ... – Peter Duniho May 17 '20 at 17:26
  • ... i.e. no implementation of `INotifyPropertyChanged`. They are asking how _generally_ attached properties work, and frankly the answer you posted does nothing to address the question that was really asked. – Peter Duniho May 17 '20 at 17:26
  • the question: "How then does ScrollViewer know that a ScrollViewer.CanContentScrollProperty property has been changed?". Title is generalized. "PropertyChanged function" much more likely means PropertyChangedCallback. Feel free to downvote more - even if it is based on your misunderstaning and not on posts content quality – ASh May 17 '20 at 17:29

2 Answers2

-1

Unfortunately, it was a while the last time I played with WPF but from what I remember/found they don't use INotifyPropertyChanged.

INotifyPropertyChanged is intended to broadcast changes in a model only (on your data).

UI controls inherit from DependencyObject class - which is one part of how their magic comes from. The other part is that UI control's properties use DependencyProperty (like your attached properties).

Some quotes from https://learn.microsoft.com/en-us/dotnet/desktop-wpf/data/data-binding-overview :

The target property must be a dependency property. Most UIElement properties are dependency properties, and most dependency properties, except read-only ones, support data binding by default. (Only types derived from DependencyObject can define dependency properties; and all UIElement types derive from DependencyObject.)

and

To detect source changes (applicable to OneWay and TwoWay bindings), the source must implement a suitable property change notification mechanism such as INotifyPropertyChanged. See How to: Implement property change notification for an example of an INotifyPropertyChanged implementation.

Then you can found :

Although not shown in the figure, it should be noted that the binding source object is not restricted to being a custom .NET object. WPF data binding supports data in the form of .NET objects and XML. To provide some examples, your binding source may be a UIElement, any list object, an ADO.NET or Web Services object, or an XmlNode that contains your XML data. For more information, see Binding sources overview.

In the Binding sources overview, you can read that INotifyCollectionChanged and INotifyPropertyChange are the interfaces to implement to support notification.

For ADO.NET objects IBindingList is the interface doing the job. (this would be the other documented binding method)

For CLR you still need to implement INotifyCollectionChanged (they refer you to the "Implementing a Class for the Binding Source chapter")

As for DependencyObject well... they do it by themself.

0xCDCDCDCD
  • 364
  • 1
  • 3
  • 16
-1

On the call stack, we can assume that a change in the value of a property is caught through some kind of XAML trigger and assigned to the ScrollContentPresenter.CanContentScrollProperty property

enter image description here

DmitryB
  • 455
  • 1
  • 5
  • 18
  • StyleHelper is WPF internals and doesn't really matter. CanContentScrollProperty DP has a callback, only not in ScrollViewer. See my answer with references. And don't forget to use [WPF] tag for WPF questions: without it they are easily missed in a flood of C# questions – ASh May 17 '20 at 17:21