将对象的属性分配给列表视图的更好方法是什么?

时间:2017-09-12 15:21:41

标签: c# entity-framework listview

我的代码工作正常,但我正在寻找一个更简单的解决方案来应用我的应用程序。我有一个对象模型Person,其中包含3个属性int Idstring Nameint Mode。这将是它现在的属性,以保持简单,但我想它可能达到15个属性。

我从数据库助手中获取内容。

Person n = db.GetPersonByName("hello");
List<string> str = ConvertObjectToStringList(n);

for (int i = 0; i < str.Count; ++i)
{ 
    dataContentListView.Items.Add(str[i]);
}

我正在手动转换内容。

private List<string> ConvertObjectToStringList(Person person)
{
    List<string> str = new List<string>();
    str.Add(person.Id.ToString());
    str.Add(person.Name);
    str.Add(person.Admin.ToString());
    return str;
}

我坚信这不是最好的解决方案,所以如果你能想到别的什么,请告诉我。

编辑1:

我正在使用通用Windows应用程序

编辑2: (我使用的解决方案) Mong Zhu建议使用数据绑定。这是更好的,因为我的代码将更干净,我的xaml将处理它将如何显示。

<ListView x:Name="restaurantListView" BorderThickness="2" BorderBrush="Green" HorizontalAlignment="Left" Height="217" Margin="341,284,0,0" VerticalAlignment="Top" Width="674">
        <ListView.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="50"/>
                        <ColumnDefinition Width="100"/>
                        <ColumnDefinition Width="50"/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Text="{Binding Id, Mode=OneWay}" Grid.Column="0"/>
                    <TextBlock Text="{Binding Name, Mode=OneWay}" Grid.Column="1"/>
                    <TextBlock Text="{Binding Admin, Mode=OneWay}" Grid.Column="2"/>
                </Grid>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

3 个答案:

答案 0 :(得分:1)

你可以使用反射。

using System.Reflection;


private List<string> ConvertObjectToStringList(Person person)
{
    List<PropertyInfo> pi = person.GetType().GetProperties(
        System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance).ToList();

    return pi.Select(x => x.GetValue(person).ToString()).ToList();            
}

说明:

这将扫描所有属性,并将每个public实例属性的值作为字符串获取到List<string>

这里的优点是您不需要关心将来是否可以添加更多属性。它们会显示在您的列表中。

如果您使用ListBox,则只需将列表绑定为DataSource

listBox1.DataSource = ConvertObjectToStringList(pers);

答案 1 :(得分:0)

尝试,

Person pr = new Person();
List<string> str = pr.GetType().GetProperties().Select(p =>  p.GetValue(pr).ToString()).ToList();

它会将所有属性转换为字符串列表

答案 2 :(得分:0)

如果性能不是很重要,简单反射版本更容易理解,但如果性能很重要,则应考虑使用可在运行时编译为IL的表达式树。这些将为您提供无需编写代码但为您提供出色性能的好处(您应该测试但我的谈话速度要快20倍)

我将如何解决您的问题:

public class Program
{
    public static string ConvertToString(object value)
    {
        return value == null ? null : value.ToString();
    }

    // We cache the adders they are expensive to create but fast to execute, create once use many times 
    public static Lazy<List<Action<Person, List<string>>>> PropertyAdders = new Lazy<List<Action<Person, List<string>>>>(() => CreateAdders<Person>());

    public static List<Action<T, List<string>>> CreateAdders<T>()
    {
        // The convert to string method we use for converting the property value to a string
        var converterMethod = typeof(Program).GetMethod("ConvertToString");
        // The add method of the list
        var addMethod = typeof(List<string>).GetMethod("Add");
        // Array of actions one for each property in the object
        var result = new List<Action<T, List<string>>>();
        foreach (var prop in typeof(T).GetProperties())
        {
            //We want to create a lambda that essentially looks like this:
            // (o, list) => list.Add(ConvertToString((object)o.Prop));
            // We create the two lambda parameters
            var item = Expression.Parameter(typeof(T));
            var list = Expression.Parameter(typeof(List<string>));

            // We create the actual lambda expression 
            var adderExp = Expression.Lambda<Action<T, List<string>>>(
                Expression.Call(list, addMethod, // Call to list.Add
                    Expression.Call(converterMethod, // Call to Program.ConvertToString
                        Expression.Convert( //Conversion of property value to object
                            Expression.MakeMemberAccess(item, prop), // member acecss o.Prop
                        typeof(object))
                    )
                ), item, list
            );

            result.Add(adderExp.Compile());
        }
        return result;
    }
    private static List<string> ConvertObjectToStringList(Person person)
    {
        List<string> str = new List<string>();
        foreach (var adder in PropertyAdders.Value)
        {
            adder(person, str);
        }
        return str;
    }

    public static void Main()
    {
        ConvertObjectToStringList(new Person { Admin = 1, Id = 1, Name = "adas" });
    }
}