English 中文(简体)
silverlight 3 collection binding
原标题:

Someone please help me understand why this binding does not work...

I have a class called SelectionManager with a property called dates which is populated by a WCF service. The property is an array of structs which bundles a DateTime and an integer count of business objects.

public class SelectionManager : INotifyPropertyChanged {

    ... other properties ...

    public DQMServiceDateCountPair[] dates { get; private set; }

    public event PropertyChangedEventHandler PropertyChanged;

    public void NotifyPropertyChanged(string propertyName) {
        if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); }
    }

I have another class called DateSelector which has a DependencyProperty called pairs setup to be the binding target of dates .

public partial class DateSelector : UserControl {

... other stuff ...

public static readonly DependencyProperty pairsProperty = DependencyProperty.Register(
    "pairs",
    typeof(DQMServiceDateCountPair[]),
    typeof(DateSelector),
    new PropertyMetadata(new DQMServiceDateCountPair[0])
);

public DQMServiceDateCountPair[] pairs {
    get { return (DQMServiceDateCountPair[])GetValue(pairsProperty); }
    set { 
        Debug.WriteLine("adding dates");
        SetValue(pairsProperty, value);
        dateMode = DateMode.Years;
    }
}

}

In my MainPage.xaml, I have a line like this:

<date:DateSelector x:Name="dateSelector" pairs="{Binding dates}" />

It s weird, because all my other bindings in MainPage.xaml update correctly, including a ComboBox bound to dates . My UserControl however, will not update. The Debug.Writeline doesn t get called in the set statement of the pairs property.

In playing around with it, I ve tried making the DQMServiceDateCountPair[] property into an ObservableCollection and implementing INotifyCollectionChanged, but that doesn t help.

If I leave either the source property or the target property as an array, and make the other an ObservableCollection, then I get a binding error that says it can t automatically convert one to the other, so Silverlight seems aware of the binding, it just doesn t update it.

Can anyone help?

P.S. I m using Silverlight 3.

最佳回答

So, here s what what going on. The binding has been working perfectly well this whole time. For the past week I ve been struggling with this, it s been happily updating along--but because of a faulty assumption on my part, I could never see it.

In case anyone else harbors this faulty assumption, let me spell it out:

The GetValue and SetValue calls are not made automatically by virtue of the fact that you are declaring a Dependency Property. The "new PropertyMetadata()" part of the declaration has an overload that takes a callback method. In this callback method, you have to set the property value yourself. For instance, in my code, I made this the PropertyMetadata call:

new PropertyMetadata(new PropertyChangedCallback(OnPairsPropertyChanged))

and the callback method reads like this:

private static void OnPairsPropertyChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) {
    ((DateSelector)d).pairs = (DQMServiceDateCountPair[])e.NewValue;
}

Thanks to everyone who tried to help!

问题回答

Try changing your code as follows:
1. Add DataMember/DataContract attributes
2. Make "set" public

[DataContract]
public class SelectionManager : INotifyPropertyChanged {

    [DataMember]
    public DQMServiceDateCountPair[] dates { get; set; }

    public event PropertyChangedEventHandler PropertyChanged;

    public void NotifyPropertyChanged(string propertyName) {
        if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); }
    }

Whats actually wierd is that the other stuff is working when you ve coded your class the way you have. My guess is that the dates array gets set by some code that runs internally in your selection manager on completion of a WCF request.

Howerver whilst you have implemented INotifyPropertyChanged you aren t actually raising the event that it defines. You can t really combine INotifyPropertyChanged with the Auto-property C# syntax. You need this:-

public SelectionManager : INotifyPropertyChanged
{
   private DQMServiceDateCountPair[] myDates;
   public DQMServiceDateCountPair[] dates
   {
     get { return myDates; }
     set
     {
       myDates = value;
       NotifyPropertyChanged("dates");
     }
     // rest of your code
}




相关问题
Silverlight Rich text box control

Our team decided that we need our own custom Rich text box control for Silverlight app we are developing. We looked at existing controls mentioned at A good rich text control for Silverlight but ...

Silverlight ImageBrush not rendering (with Bing Map Control)

I m trying to add an image to a Pushpin instance from the Silverlight Bing Map Control, but I can t seem to get it to render (the pushpin renders fine). This is probably a general WPF question rather ...

Silverlight OpenFileDialog DoEvents equivalent

I m processing large files after they are selected by the user. My code looks like the following: if (FileDialog.ShowDialog() == true) { // process really big file } This freezes up the UI so ...

list of controls with templates in silverlight

Does anyone know where to find a list of controls that you can set the template on in Silverlight? I ve wasted several hours now trying to create control templates only to find that the control doesn ...

Silverlight, Updating the UI during processing

I have a simple silverlight multifile upload application, and i want to provide the user with some feedback, right now its only in a test phase and i dont have the webservice. Somehow i cant get the ...

Silverlight 3 - FindName returns null

This looks a bug to me.. Using Silverlight 3 and i have a user control defined in XAML and trying to access the object during runtime returns a null. <Grid> <common:CommonGridEditPanel x:...

silverlight 3 collection binding

Someone please help me understand why this binding does not work... I have a class called SelectionManager with a property called dates which is populated by a WCF service. The property is an ...

热门标签