首页 > 解决方案 > 如何在 WPF 中显示和绑定数据属性的变量编号(和类型)

问题描述

我有一个对象类型(称为“车辆”),它可以具有可变数量的属性,每个属性都有不同的类型(有些属性是一个数字,有些是一个属性中的三个数字)。属性的顺序很重要(它们是几何变换)。

List我已经在一个集合中捕获了车辆类的属性。类的快速摘要(假设这些都是具有基础字段的属性):

* 请参阅下面的编辑 *

class Transformation 
{
    string Type;   // Might make sense to make this an enum
    float[] Value; // This always holds either 1, 3, or 5 values depending on Type.
}

class Vehicle 
{
    List<Transformation> MyTransformations;
}

当我选择一个特定的vehicle实例时,我想在数据面板中显示转换并绑定到它们,以便用户可以编辑它们(并添加/删除转换)。

在 WPF 中实现这一点的最佳策略是什么?我是否StackPanel通过代码构建可滚动的?有没有一种“聪明”的方法可以通过类型模板来做到这一点?在一个类中保存不同长度的转换是否是错误的(我是否需要为每种转换类型分成不同的类)?

我设想数据面板看起来像这样:

转型 
旋转 6.7 2.3 8.7
统一比例 1.0
翻译 2.2 2.0 1.0

在右侧运行滚动条,因为我不知道每个对象可能有多少转换。

* 编辑 * 根据评论和进一步实验中的建议,我为 3 种属性创建了 3 个单独的类。它们都派生自,Transformation因此List<Transformation>我的Vehicle班级中仍然有一个。

所以我现在的问题是如何构建一个包含可变数量Transformation对象的可滚动显示?

标签: c#wpfbinding

解决方案


我根据@PMV 的评论提出了一种潜在的解决方案。正如对我的原始问题的编辑中提到的,我有一个List<Transformation>保存我的转换列表,以及从 base 派生的三个不同的转换类Transformation。这三个类中的每一个都有不同类型的Value. (可能是float我创建的两个特殊类中的一个或一个,它们可以存储 3 或 5 个浮点数 - 不是在数组中)。

然后我创建了 3 个用户控件,一个用于三个派生类中的每一个。用户控件是一个基本的“网格”,每个float. 3浮点数据类型的示例如下所示:

<Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="2*"/>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="1*"/>
        </Grid.ColumnDefinitions>
        <TextBox x:Name="Type" 
            Grid.Column="0" Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
            Text="{Binding .Type, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" 
        />
        <TextBox x:Name="X" 
            Grid.Column="1" Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
            Text="{Binding .TransValue.X, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" 
        />
        <TextBox x:Name="Y" 
            Grid.Column="2" Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
            Text="{Binding .TransValue.Y, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" 
        />
        <TextBox x:Name="Z" 
            Grid.Column="3" Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
            Text="{Binding .TransValue.Z, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" 
        />

</Grid>

然后,在我的主页中,我ListView为我拥有的 3 个转换类中的每一个创建了一个带有数据的模板。两种方式的绑定按预期工作,显示看起来很完美,可以显示Transformation派生对象的任何组合。创建代码ListView

   <ListView x:Name="listView">  
        <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
                <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
            </Style>
        </ListView.ItemContainerStyle>
        <ListView.Resources>    
            <DataTemplate DataType="{x:Type mdl:Trans1}">
                <UserControls:UserControlTrans1/>
            </DataTemplate>                   
            <DataTemplate DataType="{x:Type mdl:Trans3}">
                <UserControls:UserControlTrans3/>
            </DataTemplate>    
        </ListView.Resources>    
    </ListView>

一个重要的细节是HorizontalContentAlignment财产。这会将用户控件扩展到列表的整个宽度,这使得列表看起来漂亮且统一,而不是每个条目都是不同宽度的项目。


推荐阅读