views:

480

answers:

1

I am starting out with Silverlight. I want to display a list of messages on the UI, but the databinding isn't working for me.

I have a Message class:

public class Message 
{
    public string Text { get; set; } 
    ...
}

I have the message display Silverlight User control with a Message dependency property:

public partial class MessageDisplay : UserControl
{
    public static readonly DependencyProperty MessageProperty =
        DependencyProperty.Register("Message", typeof(Message),
           typeof(MessageDisplay), null);

    public MessageDisplay()
    {
        InitializeComponent();
    }

    public Message Message
    {
        get
        {
            return (Message)this.GetValue(MessageProperty);
        }

        set
        {
            this.SetValue(MessageProperty, value);
            this.DisplayMessage(value);
        }
    }

    private void DisplayMessage(Message message)
    {
        if (message == null)
        {
            this.MessageDisplayText.Text = string.Empty;
        }
        else
        {
            this.MessageDisplayText.Text = message.Text;                
        }
    }
}

}

Then in the main control xaml I have

    <ListBox x:Name="MessagesList" Style="{StaticResource MessagesListBoxStyle}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Silverbox:MessageDisplay Message="{Binding}"></Silverbox:MessageDisplay>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox

And I bind in the control.xaml.cs code:

    this.MessagesList.SelectedIndex = -1;
    this.MessagesList.ItemsSource = this.messages;

Databinding gives no error, and it seems that there are the right number of items in the list, but a breakpoint in MessageDisplay's Message property settor is never hit, and the message is never displayed properly.

What have I missed?

+3  A: 

Your Message property is probably being set by the databinding which is bypassing your actual Message property (not the dependency one). To fix this add a PropertyChangedCallback on that property.

public static readonly DependencyProperty MessageProperty = 
  DependencyProperty.Register("Message", typeof(Message), typeof(MessageDisplay), 
  new PropertyMetadata(
    new PropertyChangedCallback(MessageDisplay.MessagePropertyChanged));


public static void MessagePropertyChanged(DependencyObject obj, DependecyPropertyChangedEventArgs e)
{
   ((MessageDisplay)obj).Message = (Message)e.NewValue;
}
  1. PropertyMetadata
  2. PropertyChangedCallback
Bryant
That does it, thanks.
Anthony