J4N
J4N

Reputation: 20771

WPF: Binding to my custom control doesn't update

I've created an user control to "Browse" for file, it is basically composed of one textbox and one button.

It has several properties, allowing me to select either a directory, an existing(open file dialog) or an inexisting file(save file dialog), specifying filter, ...

I'm using dependency properties like this:

    public static readonly DependencyProperty FilePathProperty = DependencyProperty.Register(
        "FilePath",
        typeof(String),
        typeof(BrowseFileControl),
        new PropertyMetadata(default(String), InvokeFilePathChanged)
    );
    public String FilePath { get { return (String)GetValue(FilePathProperty); } set { SetValue(FilePathProperty, value); } }

    private static void InvokeFilePathChanged(DependencyObject property, DependencyPropertyChangedEventArgs args)
    {
        BrowseFileControl view = (BrowseFileControl)property;
        view.InvokeFilePathChanged((String)args.OldValue, (String)args.NewValue);
    }
    protected virtual void InvokeFilePathChanged(String oldValue, String newValue)
    {
        InvokePropertyChanged("FilePath");
    }

In my view, I've a listbox allowing me to select which "configuration" I want to edit, and all my fields(including my usercontrol) are bound to CurrentConfiguration(and the CurrentConfiguration is Bound to the SelectedItem).

My problem: The first load is always OK, but if I select another configuration, it just doesn't update and keep the old text.

my binding is like this:

<userContols:BrowseFileControl  Grid.Row="4" Grid.Column="1" 
    Margin="2" FilePath="{Binding CurrentConfiguration.TagListFile, 
    ValidatesOnDataErrors=true, NotifyOnValidationError=true}"
    IsFolder="False" Filter="All files (*.*)|*.*" CanBeInexistantFile="False"/>

If I use a simple Textbox, with the exact same binding, it is updated correctly!

<TextBox Grid.Row="4" Grid.Column="1" 
    Text="{Binding CurrentConfiguration.TagListFile,ValidatesOnDataErrors=true, NotifyOnValidationError=true}" 
    Margin="2"/>

I also don't see any binding error in the output windows of visual studio.

So what can be wrong with my binding?

Edit: The xaml of the UserControl:

<Grid DataContext="{Binding ElementName=uxBrowseFileControl}">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="Auto"/>
    </Grid.ColumnDefinitions>
    <TextBox Padding="2" Text="{Binding FilePath, ValidatesOnDataErrors=true, NotifyOnValidationError=true}"/>
    <Button Content="Browse" Grid.Column="1" Padding="2" Command="{Binding BrowseCommand}"/>
</Grid>

uxBrowseFileControl is the name of the <UserControl>

Edit 2: In fact if I change something through the userControl, it isn't replicated in the model too :/

Edit3: I put a "Mode=TwoWay" into the binding of my currentItem.FilePath->UserControl, and it seems to work now, but why ? The TextBox with the same binding was working!

Upvotes: 3

Views: 3580

Answers (1)

Adi Lester
Adi Lester

Reputation: 25211

You should remove your DependencyProperty's change callback. You don't need any special logic in order to make Dependency Properties update the UI when they're changed - this is already built into dependency properties.

This is all you need:

public static readonly DependencyProperty FilePathProperty = DependencyProperty.Register(
    "FilePath",
    typeof(String),
    typeof(BrowseFileControl),
    new PropertyMetadata(default(String))
);

public String FilePath { get { return (String)GetValue(FilePathProperty); } set { SetValue(FilePathProperty, value); } }

You might want to also set your dependency property to bind TwoWay by default, (The Text property for the TextBox control also does this):

public static readonly DependencyProperty FilePathProperty = DependencyProperty.Register(
    "FilePath",
    typeof(String),
    typeof(BrowseFileControl),
    new FrameworkPropertyMetadata(default(String), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)
);

This way you won't have to explicitly set Mode=TwoWay whenever you bind that property.

Upvotes: 5

Related Questions