Question

I have a simple UserControl in a XAML Windows RT app. The DependencyProperty appears to be set just fine, and breakpoints in the code show the target property of 'TwitterMessage' gets the correct object at runtime, after the 'IsLoaded' event. The problem is, the binding values inside the UserControl's child controls are empty when the XAML is rendered. It's like its ignoring the values of the TwitterMessage property. Any ideas? Intellisense seems to think I'm doing it right as it autocompletes the bindings in the markup.

The Usercontrol is given a simple invocation like so:

<local:TwitterMessageUserControl TwitterMessage="{Binding Message}" Grid.Column="2" />

UserControl Markup is as follows:

<UserControl
x:Class="TwitterMessageUserControl"
...
x:Name="root">

<Border Height="85" Width="400" BorderBrush="{ThemeResource ApplicationSecondaryForegroundThemeBrush}" BorderThickness="1" >

    <StackPanel Background="{ThemeResource AppBarItemForegroundThemeBrush}" Orientation="Horizontal">
        <Image HorizontalAlignment="Left" Height="73" x:Name="Avatar" VerticalAlignment="Top" Width="73" Margin="10,5,0,0" Source="{Binding ElementName=root, Path=TwitterMessage.Tweet.AuthorAvatarUrl}"/>
        <StackPanel Margin="15,0,0,0">
            <TextBlock HorizontalAlignment="Left" x:Name="TweetText" TextWrapping="Wrap" Text="{Binding ElementName=root, Path=TwitterMessage.Tweet.Message, Mode=OneWay}" VerticalAlignment="Top" Foreground="Black" Width="300" Margin="0,10,0,0" FontSize="12"/>
            <TextBlock TextWrapping="Wrap" Text="— @someone via Twitter" x:Name="TweetFromText" Foreground="Black" Margin="0,5,0,0"/>
        </StackPanel>
    </StackPanel>
</Border>

And codebehind is as follows:

public sealed partial class TwitterMessageUserControl : UserControl
{
    public static readonly DependencyProperty TwitterMessageProperty =
        DependencyProperty.Register("TwitterMessage", typeof(TweetMessage), typeof(TwitterMessageUserControl), new PropertyMetadata(null));

    public TweetMessage TwitterMessage
    {
        get { return (TweetMessage)GetValue(TwitterMessageProperty); }
        set { SetValue(TwitterMessageProperty, value); }
    }

    public TwitterMessageUserControl()
    {
        this.InitializeComponent();
        this.Loaded += TwitterMessageUserControl_Loaded;
    }

    void TwitterMessageUserControl_Loaded(object sender, RoutedEventArgs e)
    {
        DataContext = this;
    }
}
Was it helpful?

Solution

I recreated the app quickly. When running the app I noticed this error in the debug output:

Error: BindingExpression path error: 'Message' property not found on 'App4.TwitterMessageUserControl'. BindingExpression: Path='Message' DataItem='App4.TwitterMessageUserControl'; target element is 'App4.TwitterMessageUserControl' (Name='root'); target property is 'TwitterMessage' (type 'TweetMessage')

The problem is that when you do DataContext = this; in the TwitterMessageUserControl_Loaded it will look for a Message property on itself instead of the DataContext set in your view. Comment out this line and it should work fine:

enter image description here

Additionally if you want to simplify the bindings further in the UserControl XAML you can bind to the root in the Border, and then just bind without specifying the ElementName for every binding inside that, like this:

<Border DataContext="{Binding ElementName=root}" Height="85" Width="400" BorderBrush="{ThemeResource ApplicationSecondaryForegroundThemeBrush}" BorderThickness="1" >
    <StackPanel Background="{ThemeResource AppBarItemForegroundThemeBrush}" Orientation="Horizontal">
        <Image HorizontalAlignment="Left" Height="73" x:Name="Avatar" VerticalAlignment="Top" Width="73" Margin="10,5,0,0" Source="{Binding TwitterMessage.Tweet.AuthorAvatarUrl}"/>
        <StackPanel Margin="15,0,0,0">
            <TextBlock HorizontalAlignment="Left" x:Name="TweetText" TextWrapping="Wrap" Text="{Binding TwitterMessage.Tweet.Message}" VerticalAlignment="Top" Foreground="Black" Width="300" Margin="0,10,0,0" FontSize="12"/>
            <TextBlock TextWrapping="Wrap" Text="— @someone via Twitter" x:Name="TweetFromText" Foreground="Black" Margin="0,5,0,0"/>
        </StackPanel>
    </StackPanel>
</Border>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top