简体   繁体   中英

What am I doing wrong so the data binding target doesn't get affected by data binding source

I've recently moved from Windows Forms to WPF. I started with Reed Copsey 's series ' Better User and Developer Experiences – From Windows Forms to WPF with MVVM '. On the 4th part of the series , the following code should fill text boxes with data:

<TextBox Grid.Row="0" Grid.Column="1" Text="{Binding Path=Feed.Title, Mode=OneWay}" />
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Path=Feed.Link.AbsoluteUri, Mode=OneWay}" />
<TextBox Grid.Row="2" Grid.Column="1" Text="{Binding Path=Feed.Description, Mode=OneWay}"/>

I tried to use this template-of-code to 'update a target ( TextBlock.Text ) as the source ( TextBox.Text ) updates', and that was my full XAML code:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="608.134" Width="768.284">
    <Grid>
        <Button Content="Button" HorizontalAlignment="Left" Height="28" Margin="442,56,0,0" VerticalAlignment="Top" Width="139" Click="Button_Click_1"/>
        <TextBox x:Name="TextBox1" HorizontalAlignment="Left" Height="28" Margin="56,56,0,0" TextWrapping="Wrap" Text="TextBox1" VerticalAlignment="Top" Width="237"/>
        <TextBlock HorizontalAlignment="Left" Height="66" Margin="56,168,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="285"
                   Text="{Binding Path=TextBox1.Text, Mode = OneWay}"/>

    </Grid>
</Window>

The expected value for the text of the TextBlock was "TextBox1" ( TextBox1.Text ), but the TextBlock text was actually null!

So, I checked what triggers source updates , and decided to change the binding mode to TwoWay , but I got the same result!

At last, I found "How to: Control When the TextBox Text Updates the Source" that shows how to do that. According to what Reed Copsey said in this part of his series:

Less code means less to maintain, less to test, and less to worry about.

and according to the source found on MSDN:

    <Label>Enter a Name:</Label>
<TextBox>
  <TextBox.Text>
    <Binding Source="{StaticResource myDataSource}" Path="Name"
             UpdateSourceTrigger="PropertyChanged"/>
  </TextBox.Text>
</TextBox>

<Label>The name you entered:</Label>
<TextBlock Text="{Binding Source={StaticResource myDataSource}, Path=Name}"/>

I'll be typing (roughly) the same amount of code. And such a mission (to change TextBlock by TextBox changes) can be accomplished using the normal event handlers. So my questions are:

  1. If the same mission can be accomplished with roughly the same amount of code, what makes WPF data binding so special?
  2. What was wrong with my first code?
  3. In the above MSDN code, they had to type an XAML code for both source and target. If I wanted the source to be a value inside a class, is it possible to accomplish such mission? And how?

Any help will be appreciated, Thanks in advance.

You first attempt is incorrect as the Binding path is relative to the DataContext of the TextBlock . You are trying to bind to a specific element, so you can use ElementName to specify the source and then the path is relative to this:

Text="{Binding ElementName=TextBox1, Path=Text}"

The idiomatic approach to WPF is to use MVVM. In this situation, both the TextBox and TextBlock would be bound to a property on the View Model.

The changing of the text in the TextBox would update this property which in turn would update the TextBlock . Your View Model is free from WPF View concerns and can be unit tested without involving WPF.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM