Still.Tony
Still.Tony

Reputation: 1434

Binding losing it's binding

I have a UserControl

My Bindings start out working and then drop when I interact with the control.

<Grid DataContext="{Binding RelativeSource={RelativeSource Mode=FindAncestor, 
                                            AncestorType={x:Type local:MyUserControl}}}">
    <StackPanel Orientation="Horizontal">
        <TextBox Width="100" Background="Cyan"
                 Text="{Binding Path=DP_in_UserControl,
                                FallbackValue='Fallback',
                                TargetNullValue='TargetNull',
                                UpdateSourceTrigger=PropertyChanged}"/>
        <Label Width="100" Background="Magenta"
               Content="{Binding Path=DP_in_UserControl,
                                 FallbackValue='Fallback',
                                 TargetNullValue='TargetNull'}"/>
    </StackPanel>
</Grid>

public partial class MyUserControl : UserControl
{
    public string DP_in_UserControl
    {
        get { return (string)GetValue(DP_in_UserControlProperty); }
        set { SetValue(DP_in_UserControlProperty, value); }
    }
    public static readonly DependencyProperty DP_in_UserControlProperty =
        DependencyProperty.Register("DP_in_UserControl", typeof(string),
            typeof(MyUserControl), new PropertyMetadata("UC Default"));

    public MyUserControl()
    {
        InitializeComponent();
    }
}

I have a MainWindow:

<StackPanel Margin="25">
    <local:MyUserControl VerticalAlignment="Top"
                         DP_in_UserControl="{Binding DP_in_MainWindow}"/>
    <Label Background="Yellow"
           Content="{Binding DP_in_MainWindow,
                             FallbackValue='Fallback',
                             TargetNullValue='TargetNull'}"/>
    <Button Content="Change DP__in__MainWindow"
            Click="Button_Click"/>
</StackPanel>

public partial class MainWindow : Window
{
    public string DP_in_MainWindow
    {
        get { return (string)GetValue(DP_in_MainWindowProperty); }
        set { SetValue(DP_in_MainWindowProperty, value); }
    }
    public static readonly DependencyProperty DP_in_MainWindowProperty =
        DependencyProperty.Register("DP_in_MainWindow", typeof(string),
            typeof(MainWindow), new PropertyMetadata("MW Default"));

    public MainWindow()
    {
        DataContext = this;
        InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e) =>
        DP_in_MainWindow = "Changed";
}

The window generated starts as:

Startup state

If I type in the TextBox on the UserControl (cyan), only the UserControl's Label (magenta) updates:

I typed

If I then click the Button which changes DP_in_MainWindow, only the Label defined in MainWindow (yellow) updates.

ButtonClick After Typing

BUT if I re-launch it and first click the button, all three update correctly:

ButtonClick first

And then typing again breaks the Bindings and only updates the Control's Label:

Binding broken again

What is going on here and how to I make the bindings maintain their bound-ness the XAML way. I know I could hack it together in the C# and that's most of the answers I'm seeing but there has to be a simple 'correct' way to do it.

I've experimented with all sorts of combinations of ControlTemplates and alternate bindings by name and ... just haven't hit the right combination.

Upvotes: 2

Views: 60

Answers (1)

dhilmathy
dhilmathy

Reputation: 2868

The problem could be with the Binding.Mode. Try setting TwoWay binding at your UserControl binding.

<local:MyUserControl VerticalAlignment="Top"
                     DP_in_UserControl="{Binding DP_in_MainWindow, Mode=TwoWay}"/>

Upvotes: 1

Related Questions