显示 Class 和 XAML 的所有属性

Display all properties of a Class with XAML

我是 WPF 的新手,花了几个小时寻找解决方案,但我找不到任何东西。

我想显示 class 和 DataTemplate 的所有属性:

<ItemsControl ItemsSource="{Binding Car}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding}" />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>
public class Car
{
    public int Axes { get; set; }
    public int Seats { get; set; }
    public int Doors { get; set; }
    public VehicleProperties.Car.Type Type { get; set; }
    public int MaxWeight { get; set; }
    public Fuel Fuel { get; set; }
    public double ConsumptionPer100km { get; set; }
    public bool Childseat { get; set; }
    public string Brand { get; set; }
    public string Model { get; set; }
    public int FirstRegistration { get; set; }
    public int Mileage { get; set; }
    public Transmission Transmission { get; set; }
    public int Power { get; set; }
    public bool Tempomat { get; set; }
    public SolidColorBrush Color { get; set; }
    public int PollutionClass { get; set; }
    public int EnvironmentalBadge { get; set; }
}

我怎样才能至少显示名称并正确绑定 ItemsSourceTextBlock?我需要它,因为在此之后,我将用 DataType 属性.

设计 DataTemplates

C#代码

Car car = new();
itemControl.ItemsSource = car.GetType().GetProperties();

如果您只对具体类型的 属性 名称感兴趣,您可以创建一个自定义标记扩展来接收类型并使用反射获取其 属性 信息和 returns 属性 名称可枚举。

public class PropertyNamesExtension : MarkupExtension
{
   public Type Type { get; set; }

   public PropertyNamesExtension(Type type)
   {
      Type = type;
   }

   public override object ProvideValue(IServiceProvider serviceProvider)
   {
      return Type?.GetProperties().Select(propertyInfo => propertyInfo.Name);
   }
}

在 XAML 中,您可以使用 Car 类型的标记扩展作为 ItemsSource

<ItemsControl ItemsSource="{local:PropertyNamesExtension local:Car}">
   <ItemsControl.ItemTemplate>
      <DataTemplate>
         <TextBlock Text="{Binding}" />
      </DataTemplate>
   </ItemsControl.ItemTemplate>
</ItemsControl>

如果您需要更多信息,例如每个 属性、return 的类型改为 PropertyInfo

public override object ProvideValue(IServiceProvider serviceProvider)
{
   return Type?.GetProperties();
}
<ItemsControl ItemsSource="{local:PropertyNamesExtension local:Car}">
   <ItemsControl.ItemTemplate>
      <DataTemplate>
         <TextBlock>
            <Run Text="{Binding Name, Mode=OneWay}"/>
            <Run Text="{Binding PropertyType, Mode=OneWay}"/>
         </TextBlock>
      </DataTemplate>
   </ItemsControl.ItemTemplate>
</ItemsControl>

I need that, because after this, I will design the DataTemplates with the DataType-Property.

我不知道你的确切目标是什么,但我认为你正在努力实现不同的目标。假设您要显示 Car 的单个 实例 。然后通过 属性 公开该实例并将其绑定为 ContentControlContentDataTemplate.

public Car Car { get; }
<ContentControl Content="{Binding Car}">
   <ContentControl.ContentTemplate>
      <DataTemplate DataType="{x:Type local:Car}">
         <StackPanel>
            <TextBlock Text="{Binding Brand}"/>
            <TextBlock Text="{Binding Axes}"/>
            <!-- ...other markup. -->
         </StackPanel>
      </DataTemplate>
   </ContentControl.ContentTemplate>
</ContentControl>

如果您想显示 Car 的列表,请将它们公开为任何集合,例如如果集合在运行时更改,则为 List<Car>ObservableCollection<Car>(否则添加或删除的项目将不会在用户界面中更新)。然后根据您的要求使用 ItemsControlListBoxListView 并添加 ItemsTemplate.

public ObservableCollection<Car> Cars { get; }
<ItemsControl ItemsSource="{Binding Cars}">
   <ItemsControl.ItemTemplate>
      <DataTemplate>
         <StackPanel>
            <TextBlock Text="{Binding Brand}"/>
            <TextBlock Text="{Binding Axes}"/>
            <!-- ...other markup. -->
         </StackPanel>
      </DataTemplate>
   </ItemsControl.ItemTemplate>
</ItemsControl>