首页 文章

在循环中创建ImageList对象

提问于
浏览
0

我为列表视图项创建提供了非常简单的逻辑 . 我将所有col头名称从dataGridView存储到 ColNamesForm1 数组中,然后仅比较最后5个字符是否与 (num)(cat) 字符串匹配 . 对于这两个选项,我将不同的图片附加到listview lvMoveFrom 中,使用存储在静态类 OtherFunctions 中的 Populate 函数 .

但是我的代码出了问题,因为在最后一次迭代之后它会从最后一列追加图像 - 如果第一列是(num)而最后一列是(cat),则listview中的图像都是相同的 - 来自cat image .

我该如何解决这个问题?我想知道为每列创建新的ImageList对象,但我不知道,我怎么能动态地做到这一点,例如使用循环索引i .

拜托,您能帮忙解决我的问题 .

private void Form1_Load(object sender, EventArgs e)
{
    for (int i = 0; i < ColNamesForm1.Length; i++)
    {
        if (ColNamesForm1[i].ToString().Substring(0, 4).ToUpper() != "COL_" && Regex.IsMatch(ColNamesForm1[i].ToString().Substring(4, 1), @"^\d+$") == false)
        {
            if (ColNamesForm1[i].ToString().Substring(ColNamesForm1[i].ToString().Length - 5) == "(num)")
            {
                OtherFunctions.Populate(lvMoveFrom, ColNamesForm1[i].ToString(), @"C:\pictures\num.png");
            }
            else
            {
                OtherFunctions.Populate(lvMoveFrom, ColNamesForm1[i].ToString(), @"C:\pictures\cat.png");
            }
        }
    }
}

public static void Populate(ListView lv, string itemName, string pathToPicture)
{
    ImageList img = new ImageList();
    img.ImageSize = new Size(30, 30);
    img.Images.Add(Image.FromFile(pathToPicture));
    lv.SmallImageList = img;
    lv.Items.Add(itemName, 0);
}

1 回答

  • 1

    问题

    基本上这个:

    ImageList img = new ImageList();
    img.ImageSize = new Size(30, 30);
    img.Images.Add(Image.FromFile(pathToPicture));
    lv.SmallImageList = img;
    lv.Items.Add(itemName, 0);
    

    正在向 ListView 添加新图像列表 . 你每次都传递了它(所以你有效地覆盖了它) . 其次,行:

    lv.Items.Add(itemName, 0);
    

    第二个参数是图像列表中的索引(您分配给 ListView ) . 所以给它 0 将要求 ListView 基本上从 lv.SmallImageList[0] (伪代码)中选择图像 .

    解决方案

    为了消除覆盖,我将图像设置逻辑拉出 Populate 并将其放回主方法中 . 我将分解设置逻辑:

    ImageList img = new ImageList();
    img.ImageSize = new Size(30, 30);
    
    var paths = new List<string> { @"C:\pictures\num.png", @"C:\pictures\cat.png" };
    paths.ForEach(path => img.Images.Add(MediaTypeNames.Image.FromFile(path)));
    
    lvMoveFrom.SmallImageList = img;
    

    我将所有图像路径放入 List<string> 并使用 LINQ ForEach 迭代每一个将其添加到 ImageList img . 除了我将 ListView 图像添加到 ListView 和我 only do it once 之外,与原始代码没有区别 .

    那么为了让你的代码更容易理解,我做了一些简单的重构 .

    首先是反转if语句:

    if (ColNamesForm1[i].ToString().Substring(0, 4).ToUpper() != "COL_" && Regex.IsMatch(ColNamesForm1[i].ToString().Substring(4, 1), @"^\d+$") == false)
    

    至:

    if (ColNamesForm1[i].ToString().Substring(0, 4).ToUpper() == "COL_"
                    || Regex.IsMatch(ColNamesForm1[i].ToString().Substring(4, 1), @"^\d+$"))
    {
        continue;
    }
    

    这几乎就像一个保护条款,它说如果我们不满足这些最低条件,那么转到下一个项目 .

    然后我通过减少重复简化了方法执行:

    if (ColNamesForm1[i].ToString().Substring(ColNamesForm1[i].ToString().Length - 5) == "(num)")
    {
         OtherFunctions.Populate(lvMoveFrom, ColNamesForm1[i].ToString(), @"C:\pictures\num.png");
    }
    else
    {
          OtherFunctions.Populate(lvMoveFrom, ColNamesForm1[i].ToString(), @"C:\pictures\cat.png");
    }
    

    至:

    var image = ColNamesForm1[i].ToString().EndsWith("(num)")
                    ? 0 // corresponds with the position of the image in the ImageList
                    : 1;
    
    OtherFunctions.Populate(lvMoveFrom, ColNamesForm1[i].ToString(), image);
    

    最后你会看到我改变你的 Populate 方法 . 首先,我们使用图像预填充 ListView ,然后使用该三元运算符选择要显示的图像索引 .

    代码全部在一起:

    private void Form1_Load(object sender, EventArgs e)
    {
        ImageList img = new ImageList();
        img.ImageSize = new Size(30, 30);
    
        var paths = new List<string> { @"C:\pictures\num.png", @"C:\pictures\cat.png" };
        paths.ForEach(path => img.Images.Add(Image.FromFile(path)));
    
        lvMoveFrom.SmallImageList = img;
    
        for (int i = 0; i < ColNamesForm1.Length; i++)
        {
            if (ColNamesForm1[i].ToString().Substring(0, 4).ToUpper() == "COL_"
                || Regex.IsMatch(ColNamesForm1[i].ToString().Substring(4, 1), @"^\d+$"))
            {
                continue;
            }
    
            var image = ColNamesForm1[i].ToString().EndsWith("(num)")
                            ? 0 // corresponds with the position of the image in the ImageList
                            : 1;
    
    
            OtherFunctions.Populate(lvMoveFrom, ColNamesForm1[i].ToString(), image);
        }
    }
    
    public static void Populate(ListView lv, string itemName, int imageIndex)
    {
    
        lv.Items.Add(itemName, imageIndex);
    }
    

    现在您可以进一步简化:

    private void Form1_Load(object sender, EventArgs e)
    {
        ImageList img = new ImageList();
        img.ImageSize = new Size(30, 30);
    
        var paths = new List<string> { @"C:\pictures\num.png", @"C:\pictures\cat.png" };
        paths.ForEach(path => img.Images.Add(Image.FromFile(path)));
    
        lvMoveFrom.SmallImageList = img;
    
        for (int i = 0; i < ColNamesForm1.Length; i++)
        {
            if (ColNamesForm1[i].ToString().Substring(0, 4).ToUpper() == "COL_"
                || Regex.IsMatch(ColNamesForm1[i].ToString().Substring(4, 1), @"^\d+$"))
            {
                continue;
            }
    
            var image = ColNamesForm1[i].ToString().EndsWith("(num)")
                            ? 0 // corresponds with the position of the image in the ImageList
                            : 1;
    
            lvMoveFrom.Items.Add(ColNamesForm1[i].ToString(), image);    
        }
    }
    

相关问题