我做错了什么,所以数据绑定目标不会受到数据绑定源的影响
What am I doing wrong so the data binding target doesn't get affected by data binding source
我最近从 Windows Forms 转移到了 WPF。我从 Reed Copsey's series 'Better User and Developer Experiences – From Windows Forms to WPF with MVVM'. On the 4th part of the series 开始,下面的代码应该用数据填充文本框:
<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}"/>
我尝试将此代码模板用于 'update a target (TextBlock.Text
) as the source (TextBox.Text
) updates',那是我的完整 XAML 代码:
<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>
TextBlock
文本的预期值为 "TextBox1"
(TextBox1.Text
),但 TextBlock
文本实际上为空!
所以,我检查了what triggers source updates,并决定将绑定模式更改为TwoWay
,但我得到了相同的结果!
终于找到了"How to: Control When the TextBox Text Updates the Source" that shows how to do that. According to what Reed Copsey他系列的这一部分说的:
Less code means less to maintain, less to test, and less to worry about.
并且根据在 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}"/>
我将输入(大致)相同数量的代码。并且这样的任务(通过 TextBox 更改来更改 TextBlock)可以使用正常的事件处理程序来完成。所以我的问题是:
- 如果可以用大致相同数量的代码完成相同的任务,是什么让 WPF 数据绑定如此特别?
- 我的第一个代码有什么问题?
- 在上面的 MSDN 代码中,他们必须为源代码和目标代码键入 XAML 代码。如果我希望源是 class 内的值,是否可以完成这样的任务?以及如何?
任何帮助将不胜感激,
提前致谢。
您第一次尝试是不正确的,因为 Binding
路径是相对于 TextBlock
的 DataContext
。您正在尝试绑定到特定元素,因此您可以使用 ElementName
指定来源,然后路径是相对于此的:
Text="{Binding ElementName=TextBox1, Path=Text}"
WPF 的惯用方法是使用 MVVM。在这种情况下,TextBox
和 TextBlock
都将绑定到视图模型上的 属性。
更改 TextBox
中的文本会更新此 属性,进而会更新 TextBlock
。您的视图模型没有 WPF 视图问题,可以在不涉及 WPF 的情况下进行单元测试。
我最近从 Windows Forms 转移到了 WPF。我从 Reed Copsey's series 'Better User and Developer Experiences – From Windows Forms to WPF with MVVM'. On the 4th part of the series 开始,下面的代码应该用数据填充文本框:
<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}"/>
我尝试将此代码模板用于 'update a target (TextBlock.Text
) as the source (TextBox.Text
) updates',那是我的完整 XAML 代码:
<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>
TextBlock
文本的预期值为 "TextBox1"
(TextBox1.Text
),但 TextBlock
文本实际上为空!
所以,我检查了what triggers source updates,并决定将绑定模式更改为TwoWay
,但我得到了相同的结果!
终于找到了"How to: Control When the TextBox Text Updates the Source" that shows how to do that. According to what Reed Copsey他系列的这一部分说的:
Less code means less to maintain, less to test, and less to worry about.
并且根据在 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}"/>
我将输入(大致)相同数量的代码。并且这样的任务(通过 TextBox 更改来更改 TextBlock)可以使用正常的事件处理程序来完成。所以我的问题是:
- 如果可以用大致相同数量的代码完成相同的任务,是什么让 WPF 数据绑定如此特别?
- 我的第一个代码有什么问题?
- 在上面的 MSDN 代码中,他们必须为源代码和目标代码键入 XAML 代码。如果我希望源是 class 内的值,是否可以完成这样的任务?以及如何?
任何帮助将不胜感激, 提前致谢。
您第一次尝试是不正确的,因为 Binding
路径是相对于 TextBlock
的 DataContext
。您正在尝试绑定到特定元素,因此您可以使用 ElementName
指定来源,然后路径是相对于此的:
Text="{Binding ElementName=TextBox1, Path=Text}"
WPF 的惯用方法是使用 MVVM。在这种情况下,TextBox
和 TextBlock
都将绑定到视图模型上的 属性。
更改 TextBox
中的文本会更新此 属性,进而会更新 TextBlock
。您的视图模型没有 WPF 视图问题,可以在不涉及 WPF 的情况下进行单元测试。