2
votes

I'm building a Windows Phone 8 app. I have a UserControl whose contents should get updated asynchronously. My model implements INotifyPropertyChanged. When I update a value in my model it propagates to a TextBox control as it should but not to the contents of my UserControl. What part of the puzzle am I missing or is it just not possible? Here's my reproduction scenario.

App page:

<phone:PhoneApplicationPage x:Class="BindingTest.MainPage">
  <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
    <Button Click="Button_Click" Content="Click" HorizontalAlignment="Left" Margin="147,32,0,0" VerticalAlignment="Top"/>
    <TextBlock  HorizontalAlignment="Left" Margin="69,219,0,0" TextWrapping="Wrap" Text="{Binding Bar}" VerticalAlignment="Top" Height="69" Width="270"/>
    <app:MyControl x:Name="Snafu" HorizontalAlignment="Left" Margin="69,319,0,0" Title="{Binding Bar}" VerticalAlignment="Top" Width="289"/>
  </Grid>
</phone:PhoneApplicationPage>

This is the code behind with the model class (Foo)

public partial class MainPage : PhoneApplicationPage
{
    Foo foo;
    // Constructor
    public MainPage()
    {
        InitializeComponent();
        foo = new Foo();
        ContentPanel.DataContext = foo;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        foo.Bar = "Gnorf";
    }
}

public class Foo : INotifyPropertyChanged
{
    string bar;
    public event PropertyChangedEventHandler PropertyChanged;
    void OnPropertyChanged(string name)
    {
        if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(name));
    }
    public Foo()
    {
        Bar = "Welcome";
    }
    public string Bar
    {
        get
        {
            return bar;
        }
        set
        {
            bar = value;
            OnPropertyChanged("Bar");
        }
    }
}

The UserControl xaml

<UserControl x:Class="BindingTest.MyControl">
    <TextBox x:Name="LayoutRoot" Background="#FF9090C0"/>
</UserControl>

And the code behind for the UserControl

public partial class MyControl : UserControl
{
    public MyControl()
    {
        InitializeComponent();
    }
    public static readonly DependencyProperty TitleProperty = DependencyProperty.Register("Title", typeof(string), typeof(MyControl), new PropertyMetadata("", OnTitleChanged));
    static void OnTitleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        MyControl c = (MyControl)d;
        c.Title = e.NewValue as String;
    }
    public string Title
    {
        get
        {
            return (string)GetValue(TitleProperty);
        }
        set
        {
            SetValue(TitleProperty, value);
            LayoutRoot.Text = value;
        }
    }
}

When I run the example, the UserControl TextBox will contain welcome. When I click on the button the regular TextBox updates to Gnorf but the UserControl still displays Welcome.

I also discovered that if I only bind to the UserControl the PropertyChanged event handler is null when the call to set_DataContext returns. The DataBinding infrastructure seems to infer that the binding to my UserControl is a one-time binding instead of a regular one-way binding. Any ideas?

1
DP setters/getters are never ever ever called through binding updates. Not sure if your LayoutRoot.Text = value; is meant to be run every time or only when you're calling the setter from code, but its a definite smell.user1228

1 Answers

0
votes

Try This:-

 <app:UserControl1 x:Name="Snafu" Title="{Binding Bar,Mode=TwoWay}" />

I checked It..This will work..:)