wpf - 如何将正确的上下文传递给 WPF ListView 的 ItemTemplate 中的 DataTemplate
问题描述
在我的 WPF 应用程序中有一个ListView
定义如下:
<ListView
HorizontalContentAlignment="Stretch"
DockPanel.Dock="Top"
Grid.IsSharedSizeScope="True"
ItemsSource="{Binding Path=ListSource}">
<ListView.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="ParameterIconSize" />
<ColumnDefinition
Width="Auto"
MaxWidth="100"
SharedSizeGroup="ParameterDescriptionSize" />
<ColumnDefinition
Width="Auto"
MinWidth="40"
SharedSizeGroup="ParameterValueSize" />
</Grid.ColumnDefinitions>
<Image
Grid.Column="0"
MaxHeight="50"
Source="{Binding Path=Icon}" />
<ContentPresenter
Grid.Column="2"
Content="{Binding Path=RenderValue, Converter={StaticResource RenderObjToValueConverter}}"
ContentTemplateSelector="{StaticResource ResourceKey=RenderTemplateSelector}"
/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
我已将所有内容定义Resources
如下:
<!-- TEXT -->
<DataTemplate x:Key="TextValueTemplate">
<DockPanel DataContext="{StaticResource VM}">
<TextBlock
MaxWidth="75"
Margin="5,0"
VerticalAlignment="Center"
Background="Red"
DockPanel.Dock="Top"
FontSize="14"
Text="{Binding Path=Description, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
TextTrimming="CharacterEllipsis">
<TextBlock.ToolTip>
<TextBlock
MaxWidth="100"
Text="{Binding Path=Description, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
TextWrapping="Wrap" />
</TextBlock.ToolTip>
</TextBlock>
</DockPanel>
</DataTemplate>
<!-- IMAGE -->
<DataTemplate x:Key="ImageValueTemplate">
<DockPanel DataContext="{StaticResource VM}">
<Image MaxHeight="50" Source="{Binding Path=CurrentValueImage}" />
</DockPanel>
</DataTemplate>
<!-- COMBO BOX -->
<DataTemplate x:Key="ComboValueTemplate">
<DockPanel DataContext="{StaticResource VM}">
<TextBlock
Grid.Column="1"
MaxWidth="75"
Margin="5,0"
VerticalAlignment="Center"
FontSize="14"
Text="{Binding Path=Description, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
TextTrimming="CharacterEllipsis">
<TextBlock.ToolTip>
<TextBlock
MaxWidth="100"
Text="{Binding Path=Description, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
TextWrapping="Wrap" />
</TextBlock.ToolTip>
</TextBlock>
<ComboBox/>
</DockPanel>
</DataTemplate>
<sel:ParameterVisualizationTemplateSelector
x:Key="RenderTemplateSelector"
ComboTemplate="{StaticResource ResourceKey=ComboValueTemplate}"
GraphicTemplate="{StaticResource ResourceKey=ImageValueTemplate}"
TextTemplate="{StaticResource ResourceKey=TextValueTemplate}" />
一切都编译并运行,但是我无法正确地将其传递ListViewItem
给内部数据模板。
我想要做的是能够根据图像、一些文本和组合框之间的一些逻辑(此处未显示)更改显示的内容。这些控件内部的内容在ListViewItem
. 如您所见,我尝试编写一个返回相应类型(图像、文本、数据列表)的转换器,但我缺少各种DataTemplates
.
最终编辑:根据@mm8 的回答,我发现真正的问题不是传递上下文,而是传递的属性没有被正确处理,然后在没有给出任何绑定错误的情况下不会设置任何值。
解决方案
当您DataContext="{StaticResource VM}"
在模板中设置时,您实际上DataContext
是在“覆盖”默认值,ListSource
即ListView
.
所以,如果我理解正确的话,“依赖”链类似于控制<- textItemtemplate <- ListViewItemTemplate <- Viewmodel,所以最终控制会自动“继承”对象?
您将 的 绑定ItemsSource
到ListView
一个名为的源集合属性ListSource
:
<ListView ... ItemsSource="{Binding Path=ListSource}">
'sDataContext
中的根元素(Grid
在本例中为 )的默认值将是.ListView
ItemTemplate
ListSource
这意味着如果ListSource
返回一个,IEnumerable<T>
您可以直接绑定到该类型T
的任何公共属性,ItemTemplate
前提是您没有DataContext
在模板中的某处显式设置该属性。
所以在您的示例Icon
中应该是T
(无论您的类型是什么)的属性:T
<Image Grid.Column="0"
MaxHeight="50"
Source="{Binding Path=Icon}" />
例如,如果您从 中删除DataContext="{StaticResource VM}"
,只要在从属性的转换器返回的对象中定义了一个属性TextValueTemplate
,则绑定Description
应该可以工作。Description
RenderValue
推荐阅读
- php - Laravel - 如何获取单个模型实例而不是集合,而是从 belongsToMany 获取单个模型
- scala - Scala中带有var关键字的可变映射问题
- swift - 来自 NSItemProvider 的 URL 的有效时间
- react-native - Expo SQLite 无法查询数据库
- python - 熊猫没有在不同的列上合并 - 键错误或 NaN
- javascript - 将表的 Chrome querySelector() 转换为数组
- python - 类型错误:weather_at_place() 接受 2 个位置参数,但给出了 4 个
- node.js - 詹金斯找不到模块“@angular-devkit/build-angular”
- c# - 将 Byte[] 转换为 AudioClip 后统一音频中的一些噪音
- xamarin - Xamarin XLS0502:“厚度”类型不支持直接内容