Thanks John... You helped me see that I could just look at PropertyChanged to do what I need, and that I need to be looking at the CurrentHolePattern.PropertyChanged, not the HolePatterns = new ObservableCollection
() that I was trying to hook up. I was so focused on looking for a change to the HoleList collection and using some CollectionChanged event.
In the end, I think there will be times when you really need to be watching for a CollectionChanged event to respond to. In my current case, I can get by with knowing that a change in the HoleCount property means that the HoleList collection has been changed (at least it was supposed to be).
For now, I am moving on with Property watching, but one day I'd like to explore a lower-level monitoring of changes in the the actual HoleList colleciton to respond to.
In the end, after 5+ hours of head-banging, this has helped me realized that PropertyChanged event announcement really falls fully on the programmer to make it all work. Even though you throw a INotifyPropertyChanged interface on your class, you still have to write a few support methods, an most importantly, you must be sure to properly announce every property change so the the watchers can respond. I surely expected something a little more automatic than that.
I suppose I will find with CollectionChanged that I must also tell my class when to tell everyone else that the collection has changed. Dang it, why can't it just do that for me?
Anyway, back to my program:
I'm still adhering to the different uses that I designed between RedrawScreen() and RepaintScreen: RepaintScreen() is really only required if the HoleCount changes, because I would need to remove some Ellipses from the Canvas or add some more. So, I just clear the Canvas and start all over; whereas RepaintScreen() actually works to re-arrange (move) the Ellipses and Labels that are already there. My conceren was that it would be slow to clear-the-canvas everytime a property changed, but really it's so fast that it doesn't matter. However, I'm sticking with the model I designed just as a learning example for slightly more complex coding. I'm imagining a 10,000 element model and how would you most efficiently program for that. (Not a real case, but fun to think about)!
So here is my PropertyChanged event: void CurrentHolePattern_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "HoleCount")
{
RedrawScreen(); // Clear Canvas and re-build everything!
}
else
{
RepaintScreen();// Repaint doesn't clear out the Canvas, just updates what's already there.
}
}
>Well... I found two errors to start with.
>
> private void NotifyPropertyChanged(String info)
> {
> if (PropertyChanged != null)
> {
> PropertyChanged(this, new PropertyChangedEventArgs(info));
> //CollectionChanged was null commented it off
> //CollectionChanged(this, new CollectionChangeEventArgs(CollectionChangeAction.Refresh, this.HoleList));
> }
> }
>
>Second was that repaint screen was not getting called. You are binding to CurrentHolePattern so:
>
>CurrentHolePattern.PropertyChanged += new PropertyChangedEventHandler(CurrentHolePattern_PropertyChanged);
>
>This looks like it works:
>
> public Window1()
> {
>
> HolePatterns = new ObservableCollection<HolePattern>();
> HolePatterns.CollectionChanged += new NotifyCollectionChangedEventHandler(HolePatterns_CollectionChanged);
>
> CurrentHolePattern = new HolePattern();
> CurrentHolePattern.PatternName = "Test Pattern Name";
>
> //-- Set some default values for the UI
> CurrentHolePattern.BoltCirDia = 12.0;
> CurrentHolePattern.HoleCount = 6;
> CurrentHolePattern.StartAngle = 0;
>
> HolePatterns.Add(CurrentHolePattern);
>
> InitializeComponent();
> CurrentHolePattern.PropertyChanged += new PropertyChangedEventHandler(CurrentHolePattern_PropertyChanged);
>
> SketchX0 = canvas1.Width / 2;
> SketchY0 = canvas1.Height / 2;
> SketchBoltCirRad = canvas1.Width / 2 * .7;
>
> CoordinateGrid.ItemsSource = CurrentHolePattern.HoleList;
>
> RedrawScreen();
> }
>
> void CurrentHolePattern_PropertyChanged(object sender, PropertyChangedEventArgs e)
> {
> RedrawScreen();
> //RepaintScreen(); Repaint doesn't add new holes.
> }
>