wpflistviewbindingbinding-expressions

TextBox BindingExpression UpdateSourceTrigger=Explicit


Need a TextBox in a ListView DataTemplate to call set on either LostFocus or enter key. Used UpdateSourceTrigger = Explicit and events for LostFocus and KeyUp. Problem is that I cannot get a valid reference to the BindingExpression.

XAML

    <ListView x:Name="lvMVitems" ItemsSource="{Binding Path=DF.DocFieldStringMVitemValues, Mode=OneWay}">
        <ListView.View>    
            <GridView>
                <GridViewColumn x:Name="gvcExistingValue">
                    <GridViewColumnHeader Content="Value"/>
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <TextBox x:Name="tbExistingValue"
                                Text="{Binding Path=FieldItemValue, Mode=TwoWay, ValidatesOnExceptions=True, ValidatesOnDataErrors=True, NotifyOnValidationError=True, UpdateSourceTrigger=Explicit}"
                                Validation.Error="Validataion_Error" 
                                LostFocus="tbExistingValue_LostFocus" KeyUp="tbExistingValue_KeyUp" />                                   
                        </DataTemplate>                                  
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>
            </GridView>
        </ListView.View>
    </ListView>

Code Behind NOT working

    private void tbExistingValue_LostFocus(object sender, RoutedEventArgs e)
    {
        BindingExpression be = lvMVitems.GetBindingExpression(ListView.SelectedItemProperty);
        be.UpdateSource();
    } 

be is null. I have tried ListView.SelectedValueProperty and ListView.SelectedPathProperty. If it try tbExistingValue it fails with a message "does not exists" and will not even compile. How do I get the proper BindingExpression?? Thanks.

If I set UpdateSourceTrigger = LostFocus and remove the event handlers it does call set properly. There is a valid twoway binding there. I just cannot get a valid reference to BindingExpression (be) using explicit.

It works fine for a TextBox directly on page (in a grid cell). The xaml below works:

    <TextBox Grid.Row="1" Grid.Column="1" x:Name="strAddRow" 
             Text="{Binding Path=DF.NewFieldValue, Mode=TwoWay, ValidatesOnExceptions=True, NotifyOnValidationError=True, UpdateSourceTrigger=Explicit}"
             Validation.Error="Validataion_Error" 
             LostFocus="strAddRow_LostFocus" KeyUp="strAddRow_KeyUp"/>

This BindingExpression works fine:

    private void strAddRow_LostFocus(object sender, RoutedEventArgs e)
    {
        BindingExpression be = strAddRow.GetBindingExpression(TextBox.TextProperty);
        be.UpdateSource();
    }

Solution

  • Since you apply the binding on your Textbox's Text DP, so you need to fetch the binding from there only like this -

    private void tbExistingValue_LostFocus(object sender, RoutedEventArgs e)
    {
       BindingExpression be = (sender as TextBox).GetBindingExpression(TextBox.TextProperty);
       be.UpdateSource();
    }
    

    Moreover, you haven't bind the ListView SelectedItem with any property of your ViewModel. To retrieve the binding, it should be atleast binded to some value. So, you should bind it to your FieldValueProperty then you won't get null value with your code in place.