在wpf中绑定模型的通用属性

本文关键字:属性 模型 wpf 绑定 | 更新日期: 2023-09-27 18:01:52

我有一个wpf用户控件,它绑定到一个模型(CustomerTaxModel),它有一个listview和GridView,它应该显示属性的数据类型"T"下面的资产。这种类型T是一个只有属性的类,根据我们从第三方税务核查公司收到的数据,它具有可变数量的属性。

public class CustomerTaxModel
{
    public int ID { get; set; }
    public string Name { get; set; }
    public T Assets { get; set; }

}
我的泛型"T"类如下所示。它们可能没有匹配的属性。我应该显示这种类型的数据,属性名在一列,值在第二列。在xaml中可以实现这种绑定吗?类型T接受CorporateAsset, agriculturreturns等。
public class CorporateAsset
{        
    public string CorporateOfficeName { get; set; }
    public string NetWorth { get; set; }
    public string Subsidized { get; set; }
    public string LaunchDate{ get; set; }
}

 public class AgricultureReturns
{
    public string Name { get; set; }
    public string FieldSizeinAcres { get; set; }
    public string CropType { get; set; }
    public int NoOfSeasons { get; set; }
}

我尝试的一个解决方案是绑定到KeyValuePair变量,而不是直接绑定"T"类型,我参考了链接,我尝试用静态属性类代替T类型,它动态显示数据,但当属性本身是通用的,我们如何在网格视图中显示其属性。

<UserControl x:Class="WpfApplication1.UserControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:WpfApplication1="clr-namespace:WpfApplication1" 
    mc:Ignorable="d" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    d:DesignHeight="189" d:DesignWidth="312" Width="300" Height="300">
<UserControl.Resources>
    <WpfApplication1:ConfigToDynamicGridViewConverter x:Key="ConfigToDynamicGridViewConverter" />
</UserControl.Resources>
<ListView ItemsSource="{Binding DataClass}" View="{Binding ColumnConfig, Converter={StaticResource ConfigToDynamicGridViewConverter}}"/>    

在wpf中绑定模型的通用属性

Binding.Path通过反射工作。它可以查找实际运行时对象拥有的任何公共实例属性。这就是为什么WPF控件的DataContext属性可以是Object类型。就WPF而言,您的Assets属性也可以是对象,但是没有理由放弃模型中的强类型。WPF什么都吃。

这给了我一个TextBlock,上面写着"Fred":

public MainWindow()
{
    InitializeComponent();
    DataContext = new CustomerTaxModel<AgricultureReturns>()
    {
        Assets = new AgricultureReturns() { Name = "Fred" }
    };
}
XAML:

<TextBlock Text="{Binding Assets.Name}" />

如果你有一个CustomerTaxModelObservableCollection,一个常见的模式是有一堆DataTemplates, Assets可能是不同的类型。这些都是很蹩脚的模板,但你懂的。

<ItemsControl ItemsSource="{Binding TaxModels}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Name}" />
                <!-- DataTemplates in Resources will be used here automagically -->
                <ContentControl Content="{Binding Assets}" />
            </StackPanel>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
    <ItemsControl.Resources>
        <DataTemplate TargetType="{x:Type models:AgricultureReturns}">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Name}" />
                <TextBlock Text="{Binding FieldSizeinAcres}" />
                <!-- etc -->
            </StackPanel>
        </DataTemplate>
        <DataTemplate TargetType="{x:Type models:CorporateAsset}">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding CorporateOfficeName}" />
                <TextBlock Text="{Binding NetWorth}" />
                <!-- etc -->
            </StackPanel>
        </DataTemplate>
    </ItemsControl.Resources>
</ItemsControl>