3

I was looking at this question, but I don't understand how to actually USE the created AttachedProperty. The problem is trying to have a binding on the source of the WebBrowser control.

The code there looks like:

public static class WebBrowserUtility
{
public static readonly DependencyProperty BindableSourceProperty =
    DependencyProperty.RegisterAttached("BindableSource", typeof(string), typeof(WebBrowserUtility), new UIPropertyMetadata(null, BindableSourcePropertyChanged));

public static string GetBindableSource(DependencyObject obj)
{
    return (string) obj.GetValue(BindableSourceProperty);
}

public static void SetBindableSource(DependencyObject obj, string value)
{
    obj.SetValue(BindableSourceProperty, value);
}

public static void BindableSourcePropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
    WebBrowser browser = o as WebBrowser;
    if (browser != null)
    {
            string uri = e.NewValue as string;
            browser.Source = uri != null ? new Uri(uri) : null;
    }
}
}

and

<WebBrowser ns:WebBrowserUtility.BindableSource="{Binding WebAddress}"
            ScrollViewer.HorizontalScrollBarVisibility="Disabled" 
            ScrollViewer.VerticalScrollBarVisibility="Disabled" 
            Width="300"
            Height="200" />

The WebAddress, what is that exactly? This is my understanding (which is probably wrong):

  • There's an AttachedProperty that can be attached to any object, and in this particular case, it is basically just attaching a property called BindableSource which is of type String.
  • When we have the "{Binding WebAddress}" it means that in some c# code somewhere that handles this .xaml file there's something that looks like:

    public String WebAddress
    { 
        // get and set here? not sure
    }
    
  • And to take advantage of the property changed, I can called RaisedPropertyChanged and it will fire that static method up there?

Even when I look at it, it doesn't seem right, but I can't find anything online to help me.

Community
  • 1
  • 1
vinceh
  • 3,490
  • 1
  • 21
  • 24

1 Answers1

2

There's an AttachedProperty that can be attached to any object, and in this particular case, it is basically just attaching a property called BindableSource which is of type String.

You might want to read the MSDN article on attached properties.

It is rather simple: Dependency properties work with dictionaries in which controls are associated with their values for a property, this makes it quite easy to add something like attached properties which can extend a control.

In the RegisterAttached method of the attached property a PropertyChangedCallback is hooked up which will be executed if the value changes. Using a dependency property enables binding which is the point of doing this in the first place. All the property really does is call the relevant code to navigate the browser if the value changes.


When we have the "{Binding WebAddress}" it means that in some c# code somewhere that handles this .xaml file there's something that looks like [...]

The binding references some public property or depedency property (not a field) called WebAddress inside the DataContext of the WebBrowser. For general information on data-binding see the Data Binding Overview.

So if you want to create a property which should be a binding source you either implement INotifyPropertyChanged or you create a DependencyProperty (they fire change notifications on their own and you normally do only create those on controls and UI-related classes)

Your property could look like this:

public class MyModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }

    private string _webAddress;
    public string WebAddress
    {
        get { return _webAddress; }
        set
        {
            if (value != _webAddress)
            {
                _webAddress = value;
                NotifyPropertyChanged("WebAddress");
            }
        }
    }
}

Here you have to raise the PropertyChanged event in the setter as you suspected. How to actually declare working bindings in XAML is a rather broad topic sp i would like to direct you to the aforementioned Data Binding Overview again which should explain that.


And to take advantage of the property changed, I can called RaisedPropertyChanged and it will fire that static method up there?

The event is fired to trigger the binding to update, this in turn changes the value of the attached property which in turn causes the PropertyChangedCallback to be executed which eventually navigates the browser.

H.B.
  • 166,899
  • 29
  • 327
  • 400