views:

48

answers:

2

I have a progress bar bound to 2 integer values - One is the total seconds and the other is the seconds left (which counts down on a timer: always <= Total seconds).

I have the LayoutRoot datacontext set to my top level object (of which BlindSet is a property -see code).

When I run the project the progress bar updates perfectly. It counts down the number of seconds as expected. I then change the datacontext by instantiating a new object and setting it to the BlindSet class. I use DataChanged notification events to let the UI know it has changed. This also works well - all other controls, EXCEPT the progress bar, update accordingly.

It's got me baffled, so I simplified it down to this:

2 textblocks and the progress bar, all bound to the same values. The datacontext is set higher up so it's the same for all of them.

The textblocks show the correct values counting down. (BlindSet.TimeLeftInCurrentBlind.TotalSeconds counts down on a timer) but the progress bar never updates again after I change the datacontext. I even tried rebinding it after the datacontext change but that did not help.

I also bind the ToolTip on the progress bar to the same value as Value is set to - and when you hover over the non-updating progress bar you can see it counting down correctly... but the progress bar does not show it.

Either I am doing something really stupid (possible ;) or it is a bug in the progress bar control.

xaml:

<TextBlock Text="{Binding BlindSet.CurrentBlind.SecondsPerBlind}"  />
<TextBlock Text="{Binding BlindSet.TimeLeftInCurrentBlind.TotalSeconds}" />

<ProgressBar Minimum="0" Maximum="{Binding BlindSet.CurrentBlind.SecondsPerBlind}" Value="{Binding BlindSet.TimeLeftInCurrentBlind.TotalSeconds}" ToolTipService.ToolTip="{Binding BlindSet.TimeLeftInCurrentBlind.SecondsPerBlind}" />

Code behind:

LayoutRoot.DataContext = tournament;

tournament has a BlindSet object, but I don't think this is part of the problem as the other controls are updating fine:

  public Blindset BlindSet
    {
        get { return blindset; }
        set
        {
            if (blindset != value)
            {
                blindset = value;
                OnPropertyChanged("BlindSet");
                OnPropertyChanged("CurrentBlind");
            }
        }
    }

Update: Perhaps there is some internal state that needs to be reinitialised with the new max and value values when the datacontext changes (the values are very different, e.g 1200 seconds or 120 seconds).

When I bind to a new BlindSet object with the same values (ie. 1200 seconds) then it works as expected - so I think I need to somehow give it a kick to recalculate the small or large value changes - any idea how?!

A: 

I've just read this in the comments section of a blog article, I hope it helps.

Just so everyone knows. The ProgressBar (at least as of Silverlight 3 - Sept 2009) does not work very well with databinding. It only partially works. So you may want to consider this in your design until such time as it is fixed.
1) Cannot change DataContext without changing to Null first. Thus inherited bindings usually don't work.
2) Visibility cannot be databound. (You can try, but it always works as if you had set Mode=OneTime)
3) Other bindings don't seem always stable either...
Hope that helps somebody avoid frustration.

Bertrand Marron
Ok thanks, in the end I created it programatically and recreate it each time the datacontext needs to change.
Rodney
A: 

Well, assuming you're implementing INotifyPropertyChanged on the object, you have to state that "public Blindset BlindSet" and that each of the properties on the instance of "BlindSet" are changing... Am I correct you also need to use two-way binding for that, or am I thinking of input values?


To make that clearer... each of the properties on BlindSet.CurrentBlind.{property here} needs to announce that it has chanaged as well, and the BlindSet.CurrentBlind property needs to announce it changed.

Richard B
Thanks Richard, but I am notifying the UI of new changes- the other controls that are bound to the same values update fine. It is something in the progress bar.
Rodney