【发布时间】:2021-08-02 22:39:10
【问题描述】:
我正在尝试创建一个通用 ListView 页面,我可以在其中显示 List<object> 上的所有项目,我不知道将显示哪些字段。
我打算在导航时接收List<object> 和我想在Dictionary<string, string> 中显示的字段,其中第一个字符串表示该字段是标题、子标题或图像,第二个字符串表示名称我想作为参数绑定到 header/subheader/image 的属性。
目前我的 C# 代码如下所示:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
var param = (Dictionary<string, object>)e.Parameter;
_ItemsList = (List<object>)param["itemsList"];
var fields = (Dictionary<string, string>)param["fields"];
_DetailsPage = (Type)param["detailPage"];
ObjListView.ItemsSource = UniversalAutoSuggestBox.ItemsSource = _ItemsList;
}
我的问题是数据绑定是在我的视图 XAML 上的 DataTemplate 上定义的:
<DataTemplate x:Key="NormalItemTemplate">
<Grid MinWidth="350"
Margin="5">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Ellipse Grid.Row="0" Grid.RowSpan="2"
Width ="32"
Height="32"
Margin="6"
VerticalAlignment="Center"
HorizontalAlignment="Center">
<Ellipse.Fill>
<ImageBrush x:Name="LogoImage" ImageSource="{Binding Image}"/>
</Ellipse.Fill>
</Ellipse>
<TextBlock x:Name="HeaderTextBlock"
Grid.Row="0"
Grid.Column="1"
Text="{Binding Header}"
Style="{ThemeResource BaseTextBlockStyle}"
Margin="12,6,0,0"/>
<TextBlock x:Name="FooterTextBlock"
Grid.Row="1"
Grid.Column="1"
Text="{Binding Subheader}"
Style="{ThemeResource BodyTextBlockStyle}"
Margin="12,0,0,6"/>
</Grid>
</DataTemplate>
我想知道是否有一种方法可以动态地将数据绑定更改为从字段字典中获取的属性,以及这样做的最佳解决方案是什么,或者在那里使用不同的方法更好。
【问题讨论】:
-
最简单的方法来显示可能将该列表绑定到 DataGrid 并让网格自动生成列的任何内容的列表。这当然不会好看。如果您想在代码中控制绑定,请查看 BindigOperations 和 Binding 类本身。至少这是 NET Framework/WPF、.NETCore/WPF 的一种方式。我对UWP一无所知。也许这里的 API 略有不同。
-
我的问题不是更改绑定本身,而是访问它们,因为它们位于 DataTemplate 中。我不能直接直接修改 XAML 对象。
-
加载“UI”后,您还可以访问通过模板生成的 uielements(以及它们的绑定)。但据我所知,您无法在加载 DataTemplate 之前对其进行入侵。至少没有合理的努力。
-
另一种方法是分析每个属性的(数据)类型,并根据数据类型提供适当的模板。对于列表视图,您可以利用
GridViewColumn的CellTemplateSelector属性来适当地定制数据模板。也许您需要一个绑定数据的包装器,它充当要绑定的名称的适配器,而您事先并不知道。 -
@lidqy 你不能举个例子来说明如何做到这一点吗?