3
votes

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!

1
How does the specific part of your usercontrol looks?dowhilefor
@dowhilefor I updated my question, is this what you wanted?J4N

1 Answers

4
votes

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.