如题,我有一个自定义flowlayoutpanel控件,上面动态添加picturebox控件来显示图片,我用的是pic控件的异步加载图片方式
一下为基本代码,当我选择一些图片的时候它已经加载到flowlayoutpanel控件上了,但是pic不显示图片,在显示全部图片的时候还闪烁一下,我想实现的是当加载一张图片pic就显示这张图,并且不显示,求高手解答,另外我已经设置doublebuffered的属性以及任何可能导致闪烁的属性了private void button4_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Multiselect = true;
            ofd.Filter = "(*.jpg,*.gif,*.jpeg)|*.jpg;*.gif;*.jpeg|*.jpg|*.jpg|*.gif|*.gif|*.jpeg|*.jpeg";
            ofd.FilterIndex = 1;
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                //scaner.FilePath = ofd.FileName;
                for (int i = 0; i < ofd.FileNames.Length; i++)
                {
                    FileInfo fi = new FileInfo(ofd.FileNames[i]);
                    fi.CopyTo(scaner.FilePath + "\\" + fi.Name,true);
                    Thread.Sleep(500);
                    object url = scaner.FilePath + "\\" + fi.Name;
                    Thread th = new Thread(new ParameterizedThreadStart(imgList.AddImage));
                    th.Start(url);
                    //imgList.AddImage(scaner.FilePath + "\\" + fi.Name);
                    Thread.Sleep(500);
                }
            }
            
        }/// <summary>
        /// 添加
        /// </summary>
        /// <param name="path">图片路径</param>
        public void AddImage(string path)
        {
            PictureBox pb = new PictureBox();
            CheckBox cb = new CheckBox();            pb.AllowDrop = true;
            pb.Name = this.Controls.Count.ToString();            byte[] image = SetImageToByteArray(path);
            Image img = SetByteToImage(image);            pb.Image = ResizeImage(img, 100, 150);            //pb.Image = Image.FromFile(path);
            //pb.WaitOnLoad = false;
            //pb.LoadAsync(path);            pb.Tag = path;
            pb.Size = new Size(picWidth, picHeight);
            pb.SizeMode = PictureBoxSizeMode.StretchImage;
            pb.BorderStyle = BorderStyle.FixedSingle;
            pb.MouseDown += new MouseEventHandler(Pic_MouseDown);
            pb.DragDrop += new DragEventHandler(Pic_DragDrop);
            pb.DragEnter += new DragEventHandler(Pic_DragEnter);
            pb.MouseEnter+=new EventHandler(pb_MouseEnter);
            pb.MouseUp+=new MouseEventHandler(pb_MouseUp);            PictureBox pbDel = new PictureBox();
            pbDel.Tag = pb;
            pbDel.Size = new Size(15, 15);
            pbDel.Image = deleteImage;
            pbDel.Location = new Point(0, pb.Height - pbDel.Height);
            pbDel.BackColor = Color.Transparent;
            pbDel.Click += new EventHandler(PicDel_Click);            cb.Name = this.Controls.Count.ToString();
            cb.Tag = path;
            cb.Size = new Size(15, 15);
            cb.Location = new Point(pb.Width - 15, pb.Height - cb.Height);
            cb.Click+=new EventHandler(cb_Click);            CheckForIllegalCrossThreadCalls = false;
            pb.Controls.Add(cb);
            pb.Controls.Add(pbDel);
            this.Controls.Add(pb);
        }

解决方案 »

  1.   

    picturebox初始化的时候加上这句试试SetStyle(ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);
      

  2.   

    呃。看错了。是在 flowlayoutpanel初始化的时候。
      

  3.   

    你在打开图像的时候,就要ADDIMAGE,这个时候是不会闪烁的,if (ofd.ShowDialog() == DialogResult.OK)            {ADDIMAGE}在这个里面加图像,你没有调用ADDIMAGE,所以不会显示图像。
      

  4.   

    flowlayoutpanel是系统的控件还是自定义控件?
    如果是继承的FlowLayoutPanel就在初始化的时候加;
    SetStyle(ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);
    要不然就要加在窗体初始化的时候;
    另外,每加一个图片执行一次 
    this.Refresh();
      

  5.   

    他是在线程中调用的AddImage
    要实现异步图片加载。
      

  6.   

    他是在线程中调用的AddImage
    要实现异步图片加载。
    我用的是 picturebox控件自带的异步加载方法都不好用
      

  7.   

    他是在线程中调用的AddImage
    要实现异步图片加载。
    我用的是 picturebox控件自带的异步加载方法都不好用
    this.Controls.Add(pb);
    我以前用VB.Net做过类似的西,
    好像这个地方要用委托来做;
      

  8.   

    使用双缓冲技术了,加入下面代码:SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
    SetStyle(ControlStyles.AllPaintingInWmPaint, true);
      

  9.   

    异步方式都写错了当然显示不出来1你用线程操作没用到委托就向窗体控件直接进行Add。
    2.CheckForIllegalCrossThreadCalls = false;这个也不要把这东西放到线程的方法里,在窗体的构造函数里操作就是了。如果要在所有线程执行完后。那就把他放到for的外边去。
    3。你在for循环内加Thread.Sleep(500)。相当于把主UI线程给睡了500,当然UI不干活了。