背景
最开始使用的是 TextBlock:
xml
<ItemsControl ItemsSource="{Binding CameraList}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<GroupBox>
<TextBlock Text="{Binding}" Foreground="Green"/>
</GroupBox>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
后面将,TextBlock改为TextBox后报错
xml
<ItemsControl ItemsSource="{Binding CameraList}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<GroupBox>
<TextBox Text="{Binding}" Foreground="Green"/>
</GroupBox>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
报错信息如下
首先看如何解决这个报错问题。
方案 1:使用 {Binding .}
因为 CameraList
里的每个元素就是 string
,直接使用 {Binding .}
让 TextBox
绑定当前项:
xml
<ItemsControl ItemsSource="{Binding CameraList}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<GroupBox>
<TextBox Text="{Binding .}" Foreground="Green"/>
</GroupBox>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
方案 2:绑定 Path
指定 Text
虽然 Binding .
已经可以解决问题,但你也可以显式指定 Path
:
xml
<TextBox Text="{Binding Path=.}" Foreground="Green"/>
但 Path
在绑定 List<string>
时通常可以省略。
这样就能正确绑定 List<string>
里的每个字符串到 TextBox
里。🚀且不会报错!
为啥用TextBlock这样写不报错?
TextBox
绑定报错,而 TextBlock
没有报错,主要是因为 TextBox.Text
默认是双向绑定,而 TextBlock.Text
是单向绑定。
区别分析
-
TextBox.Text="{Binding}"
(默认是Mode=TwoWay
)TextBox
的Text
绑定默认是双向绑定 (Mode=TwoWay
)。- 但是你的
CameraList
是List<string>
,其中的string
是不可修改的值类型 ,WPF 不能将TextBox.Text
的值回写到string
,所以绑定失败。
-
TextBlock.Text="{Binding}"
(默认是Mode=OneWay
)TextBlock
只需要读取string
值,不需要回写,因此不会有绑定问题。
解决方案
使用 TextBox
,可以将 Binding
设置为 Mode=OneWay
:
xml
<TextBox Text="{Binding Mode=OneWay}" Foreground="Green"/>
或者使用 {Binding .}
:
xml
<TextBox Text="{Binding .}" Foreground="Green"/>
这样 TextBox
只读 string
,不会尝试写回,就不会报错了。
总结
TextBlock.Text
只读,不回写,所以绑定string
没问题。TextBox.Text
需要写回,string
不是DependencyObject
,无法写回,所以报错。- 解决方案:使用
Mode=OneWay
或者{Binding .}
让TextBox
变成单向绑定。🚀