Text box value is not updated in ViewModel when changing in the view in WPF

Dev picture Dev · Jul 17, 2013 · Viewed 7.4k times · Source

When I change the text box value, it is not updated in the view model.

This is my text box xaml in the view

<TextBox Height="23" HorizontalAlignment="Left" Margin="153,65,0,0" Name="textBox2" VerticalAlignment="Top" Width="120" Text="{Binding Path=InstallPath, Mode=TwoWay}"/>

Full xaml for the view,

<Window.Resources>
    <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</Window.Resources>

<Grid>

    <Button Content="Configure Logger" Height="44" HorizontalAlignment="Left" Margin="402,125,0,0" Name="button1" VerticalAlignment="Top" Width="108" Click="button1_Click" />
    <Button Content="Load DB" Height="43" HorizontalAlignment="Left" Margin="402,200,0,0" Name="button3" VerticalAlignment="Top" Width="108" Click="button3_Click" />
    <TextBlock Height="23" HorizontalAlignment="Left" Margin="46,36,0,0" Name="textBlock1" Text="SQL Server" VerticalAlignment="Top" />
    <TextBox Height="23" HorizontalAlignment="Left" Margin="153,36,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" TextChanged="textBox1_TextChanged" />
    <GroupBox Header="DB Names" HorizontalAlignment="Left" Margin="54,114,0,0" Name="groupBox1" VerticalAlignment="Top" >

    </GroupBox>


    <TextBlock Text="Test bootstrapper application." Margin="10" FontSize="18" HorizontalAlignment="Center" Foreground="Red" VerticalAlignment="Top" />
    <TextBlock Height="23" HorizontalAlignment="Left" Margin="46,65,0,0" Name="textBlock2" Text="Installation Path" VerticalAlignment="Top" />
    <TextBox Height="23" HorizontalAlignment="Left" Margin="153,65,0,0" Name="textBox2" VerticalAlignment="Top" Width="120" Text="{Binding Path=InstallPath, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>

    <Ellipse Height="100" Width="100" HorizontalAlignment="Center" VerticalAlignment="Center" StrokeThickness="6" Margin="278,129,216,112"
             Visibility="{Binding Path=IsThinking, Converter={StaticResource BooleanToVisibilityConverter}}">
        <Ellipse.Stroke>
            <LinearGradientBrush>
                <GradientStop Color="Red" Offset="0.0"/>
                <GradientStop Color="White" Offset="0.9"/>
            </LinearGradientBrush>
        </Ellipse.Stroke>
        <Ellipse.RenderTransform>
            <RotateTransform x:Name="Rotator" CenterX="50" CenterY="50" Angle="0"/>
        </Ellipse.RenderTransform>
        <Ellipse.Triggers>
            <EventTrigger RoutedEvent="Ellipse.Loaded">
                <BeginStoryboard>
                    <Storyboard TargetName="Rotator" TargetProperty="Angle">
                        <DoubleAnimation By="360" Duration="0:0:2" RepeatBehavior="Forever" />
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
        </Ellipse.Triggers>
    </Ellipse>
    <StackPanel Orientation="Horizontal" VerticalAlignment="Bottom" HorizontalAlignment="Right">
        <Button Content="Install" Command="{Binding Path=InstallCommand}" Visibility="{Binding Path=InstallEnabled, Converter={StaticResource BooleanToVisibilityConverter}}" Margin="10" Height="20" Width="80"/>
        <Button Content="Uninstall" Command="{Binding Path=UninstallCommand}" Visibility="{Binding Path=UninstallEnabled, Converter={StaticResource BooleanToVisibilityConverter}}" Margin="10" Height="20" Width="80"/>
        <Button Content="Exit" Command="{Binding Path=ExitCommand}" Margin="10" Height="20" Width="80" />
    </StackPanel>
     </Grid>

ViewModel

 private string installPath;
    public string InstallPath
    {
        get { return installPath; }
        set
        {
            installPath = value;
            RaisePropertyChanged("InstallPath");                
        }

Method which consumes the text box value in WIX Bootstrapper

 protected override void Run()
 {            

    MainViewModel viewModel = new MainViewModel(this); 
    BootstrapperDispatcher = Dispatcher.CurrentDispatcher;         

    MainView view = new MainView();            
    view.DataContext = viewModel;
    this.Engine.Log(LogLevel.Verbose, "My text input is: " + view.textBox2.Text);
    viewModel.Bootstrapper.Engine.StringVariables["MyBurnVariable1"] = viewModel.InstallPath;

}

viewModel.InstallPath is empty even though I change the value in textbox, Do I miss something?

I am just following the below WIX Bootstrapper example explained in the below link, http://bryanpjohnston.com/2012/09/28/custom-wix-managed-bootstrapper-application/

Answer

Jehof picture Jehof · Jul 17, 2013

Your bindings and setups seems ok with the code you have provided.

You should note that the default UpdateSourceTrigger of the TextBox is LostFocus, so that your property is only updated when the TextBox lost focus.

You can change the UpdateSourceTrigger to PropertyChanged, so that every time Text is written in the TextBox your property gets updated.

You set up the UpdateSourceTrigger in the binding as follows

<TextBox Text="{Binding Path=InstallPath, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>