3

I have a small question but have been finding quite a few different, and mostly ambiguous, answers:

I have the following user control and I am trying to bind to a public property within that control (Events). Everyone says that I have to use the data context, however, I don't really want to do that... I just want to bind to the property from within the control's XAML...

The requirement is that the binding has to be 2 way so any changes in the ui will be reflected in the property (or rather the collection) it is bound to. Each Event object within that collection also implements INotifyPropertyChanged the same way as this control...

Any ideas would be greatly appreciated!

public partial class EventEditorWindow : UserControl, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public ObservableCollection<Event> events;
    public ObservableCollection<Event> Events
    {
        get { return this.events; }
        set
        {
            if( this.events != value )
            {
                this.events = value;
                this.RaisePropertyChanged("Events");
            }
        }
    }

    private void RaisePropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            this.VerifyPropertyName(propertyName);
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    [Conditional("DEBUG")]
    [DebuggerStepThrough]
    public void VerifyPropertyName(string propertyName)
    {
        var currentObjectType = this.GetType();

        if (currentObjectType.GetProperty(propertyName) == null)
        {
            throw new ArgumentException("Property not found", propertyName);
        }
    }
}

Thanks, Bleepzter.

bleepzter
  • 9,607
  • 11
  • 41
  • 64

2 Answers2

2

In the constructor, set DataContext = this. That will effectively make your code behind your DataContext. AFAIK, you can't completely avoid making something the DataContext.

Phil Sandler
  • 27,544
  • 21
  • 86
  • 147
  • Thanks! I will try this right away. Do I also have to add that line of code whenever I update the collection programmatically? – bleepzter May 23 '11 at 20:15
  • 1
    No - your PropertyChanged event will take care of that – ColinE May 23 '11 at 20:17
  • 1
    You shouldn't have to, no. Also, if you are just adding/removing items from the collection, you don't need to implement INotifyPropertyChanged. The observableCollection already takes care of notifying on add/remove/clear. – Phil Sandler May 23 '11 at 20:18
  • Thanks, your solution worked. The reason why the items in the collection implement INotifyPropertyChanged is because some of the properties do change. While the collection does take care of notifying the UI for changes within the collection, I discovered it doesn't notify for changes within the items themselves. Thank you so much for helping out - everything works like a charm! – bleepzter May 24 '11 at 02:24
  • No problem. The Event class should need to implement INotifyPropertyChanged--you should not need this on the collection itself (the event *property*). It's not hurting anything but should not be required. – Phil Sandler May 24 '11 at 03:03
1

You could use a RelativeSource so you don't need the DataContext:

{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type EventEditorWindow }}, Path=Events}

I use this cheat sheet from time to time.

EDIT Oops this is WPF syntax. See this post to have a look at this post to solve it in Silverlight

Emond
  • 50,210
  • 11
  • 84
  • 115
  • thank you for this cheat sheet. When I tried to implement AncestorType={x:type ...} I was getting errors of the sort "Relative Resource does not implement AncestorType"... I did however find the binding cheat sheet quite useful! – bleepzter May 24 '11 at 02:25