在C#中将图像包含为可观察集合

时间:2017-08-23 13:10:05

标签: c# image list linq observablecollection

我刚问了一个关于linq在C#中的排名的问题:Linq List Ranking in C#已经回答了。问题是根据他们的分数对我所拥有的人员进行排名。所以现在我想添加一些等于该人得分的星星。例如:

 Rank Name Score Stars
  1   John  5    *****
  2   Ed    4    ****
  3   Sara  3    ***

星星应该是一个真正的.png星形图像。我的问题是,实现这个的最佳方法是什么?这是我尝试过的一次尝试,但它不适合我:

   public class Person
    {

        public int Rank { get; set; }
        public string Name { get; private set; }
        public int Score { get; set; }
        public Image Star { get; set; }

        public Person(int rank, string name, int score, Image star)
        {
            Rank = rank;
            Name = name;
            Score = score;
            Star = star;

        }
    }

    public ObservableCollection<Person> Persons { get; set; }
    public MainWindow()
    {
        InitializeComponent();
        var lines = File.ReadAllLines(filepath);

        Persons = new ObservableCollection<Person>();
        var data = lines.Select(line => {
        var column = line.Split(',');
        var name = column[0];
        int score = int.Parse(column[1]);
        int rank =0;
        Image star = new Image();

        return new { name, score, avg, rank, star };
    });

        var groupedData = data.GroupBy(p => p.name).Select((g, i) => new { name = g.Key, rank = i + 1, score = g.Sum(p => p.score), star = new BitmapImage(new Uri(@"\Pics\MinusRate.png", UriKind.Relative))}).OrderByDescending(x => x.score);

        var persons = groupedData.Select((p, i) => new Person(i+1, p.name, p.score,p.star));

    foreach (var person in persons) {
        Persons.Add(person);
    }
    datagrid.ItemsSource = Persons;

    } 

那么将星星纳入此列表的最佳方法是什么?

1 个答案:

答案 0 :(得分:2)

在我看来,你绝对应该把它作为UI关注点。不要试图为数据的内存表示预渲染星形图像。你有那里的信息(int Score),就是这样。让其余的人做你的用户界面。

想象一下任何开发人员为非UI目的请求数据:他当然不希望代码为每个查询呈现图像,他可能想知道内存消耗(RAM和网络流量)来自何处。

一旦数据到达用户界面,您就可以进行成像。例如,如果你去GDI +,你可以像这样渲染图像:

// the icon file with one single star
var starIcon = Image.FromFile(...);

// the image of all stars (the width has to be the width of one star multiplied by the count of stars)
var image = new Bitmap(starsCount * starIcon.Width, starIcon.Height);

using (var g = Graphics.FromImage(image))
{
    for (int i = 0; i < starCount; i++)
    {
        // place the star icon to its position in the loop
        int x = (i * starIcon.Width);

        // https://msdn.microsoft.com/de-de/library/dbsak4dc(v=vs.110).aspx
        g.DrawImage(starIcon, x, 0, starIcon.Width, starIcon.Height);
    }

    g.Flush();
}

注意这更像是伪代码 - 我没有把它扔进编译器,所以它可能不会像那样编译。

更新

我在这里做了一个工作小提琴:https://dotnetfiddle.net/HPB7BR

请注意,您不需要GetImageFromURL()只是为了将图像放入该在线小提琴中。并且,因为我无法将图像显示为该小提琴中的输出,所以我选择将图像的大小显示为输出。无论如何,变量image中的图像已准备好使用。您可以更改starCount以查看图像宽度的相应变化。