PDA

View Full Version : سوال: ایجاد backgroundworker برای لود عکس های یک دایرکتوری



رامین مرادی
سه شنبه 12 دی 1396, 13:09 عصر
وقت بخیر دوستان .من با کد زیر عکسهای یک دایرکتوری رو میخونم و میریزمش توی یه پنل حالا مشکل اینجاست که تا زمانی که تمامی عکسها لود نشن فرم نشون داده نمیشه.
مد نظرم اینه که هر عکسی که لود میشه توی پنل نشون داده بشه و به مرور هم بقیه عکسها که لود میشه تو پنل قرار بگیرن. چجوری این رو توی یک بک گراند ورکر اضافه کنم؟




string[] files = Directory.GetFiles( @"D:\\FileServer\Gallery");
foreach (var filename in files)
{

if (filename.Substring(filename.Length - 2, 2) == "db")
break;

Bitmap bmp = null;
try
{
bmp = new Bitmap(filename);
}
catch (Exception ex)
{

}
var card = new PictureBox();
card.BackgroundImage = bmp;
card.Padding = new Padding(0);
card.BackgroundImageLayout = ImageLayout.Stretch;
card.MouseDown += new MouseEventHandler(card_click);
card.Size = new Size(200, 200);
card.Left = col+20;
card.Top = row ;
if (col > 400)
{
col = 0;
row += 220;
}
else
col += 220;


panel1.Controls.Add(card);
}

parvizwpf
سه شنبه 12 دی 1396, 14:30 عصر
اگه نیازه که تیکه تیکه عکسها رو بخونید پس باید تیکه تیکه هم فایلها رو لود کنید از جایی که میخواهید. بدین ترتیب که کدتون نشون میده همه چی یکدفعه ای دانلود میشه که مورد نظر شما نیست. پس باید هی یک فایل رو بگیرید و هی برید سراغ بعدی بکگراند ورکر وقتی کارش رو تموم کرد متد Completed خودش رو صدا میزنه . بنظرم باید تکه تکه رو فایلها کار کنید . یعنی به دفعات مورد نیاز بکرگراند ورکر رو برای دریافت فایل ها صدا بزنید

رامین مرادی
سه شنبه 12 دی 1396, 14:35 عصر
اگه نیازه که تیکه تیکه عکسها رو بخونید پس باید تیکه تیکه هم فایلها رو لود کنید از جایی که میخواهید. بدین ترتیب که کدتون نشون میده همه چی یکدفعه ای دانلود میشه که مورد نظر شما نیست. پس باید هی یک فایل رو بگیرید و هی برید سراغ بعدی بکگراند ورکر وقتی کارش رو تموم کرد متد Completed خودش رو صدا میزنه . بنظرم باید تکه تکه رو فایلها کار کنید . یعنی به دفعات مورد نیاز بکرگراند ورکر رو برای دریافت فایل ها صدا بزنید
پس یعنی من تو کامپلیت خودش دوباره خودشو فراخوانی کنم به شرط اینکه ایندکس اون آرایه تموم نشده باشه؟؟ درسته؟ خب حالا چجوری به اشیا فرم از داخل بک گراند ورکر دسترسی داشته باشم؟

parvizwpf
سه شنبه 12 دی 1396, 14:39 عصر
تقریبا میشه انطوری گفت . شما کد مربوط به یو آی رو نمیتونید در متد DoWrok بنویسید باید از آرگومانش استفاده کنید مثلا به این صورت :
e.Result = x
با اینکار شما دارید یک خروجی به ایونت Completed میفرستید . حالا در اون ایونت میتونید کلا با یو آی کار کنید. دوباره داخل اون اوینت با e.Result میتونید مقدار برگشتی رو بگیرید. البته نوعش object هست که دیگه باید زحمت تبدیل رو بکشید

parvizwpf
سه شنبه 12 دی 1396, 14:44 عصر
الان سرچ کردم یه چیزی شبیه کار شما دیدم اینو حتما بخونید:
https://www.codeproject.com/Tips/83317/BackgroundWorker-and-ProgressBar-demo

رامین مرادی
سه شنبه 12 دی 1396, 14:54 عصر
خب من اومدم اینو به این صورت تغییر دادم. اما یه جای کارم میلنگه و منطق برنامم درست عمل نمیکنه. عکسا دونه دونه لود میشن. اما خب هیچ وقت این کار تموم نمیشه:عصبانی++: کجای کارم اشتباهه؟؟


private void GalleryFrm_Load(object sender, EventArgs e)
{
_worker1 = new BackgroundWorker();
_worker1.DoWork += new DoWorkEventHandler(worker1_DoWork);
_worker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_worker1_RunWorkerC ompleted);
_worker1.RunWorkerAsync();
}

private void worker1_DoWork(object sender, DoWorkEventArgs e)
{

string[] files = Directory.GetFiles(@"D:\Gallery");
foreach (var filename in files)
{

if (filename.Substring(filename.Length - 2, 2) == "db")
break;

Bitmap bmp = null;
try
{
bmp = new Bitmap(filename);
}
catch (Exception ex)
{

}
var card = new PictureBox();
card.BackgroundImage = bmp;
card.Padding = new Padding(0);
card.BackgroundImageLayout = ImageLayout.Stretch;
card.MouseDown += new MouseEventHandler(card_click);
card.Size = new Size(200, 200);
card.Left = col + 20;
card.Top = row;
if (col > 400)
{
col = 0;
row += 220;
}
else
col += 220;

CreateList(card);
}


}

private void CreateList(Control card)
{
if (this.InvokeRequired)
this.Invoke((Action<Control>)AddItem, card);
else
AddItem(card);
}
private void AddItem(Control card)
{
panel1.Controls.Add(card);
}

parvizwpf
سه شنبه 12 دی 1396, 15:00 عصر
خب لینک رو دیدید؟ لینک رو من تست کردم خوراک کار شماست یه بار با اون روش برید. شاید تعداد دفعات رو اشتباه میده

رامین مرادی
سه شنبه 12 دی 1396, 15:12 عصر
خب لینک رو دیدید؟ لینک رو من تست کردم خوراک کار شماست یه بار با اون روش برید. شاید تعداد دفعات رو اشتباه میده

کد شمارو دیدم اما مربوط به یه چیز دیگس. کد رو گذاشتم تو پست 6 یه بار بخونید. خودتونم میتونید اجرا بگیرید

parvizwpf
سه شنبه 12 دی 1396, 15:29 عصر
خب اینطور که من میبینم باز هم اومدید کد یو آی رو داخل dowork نوشتید. قرار نشد حلقه فور داخل dowork باشه باید پس ار هبار خوندن یک فایل در completed باشه الان کامپلیتد کجاست؟

رامین مرادی
چهارشنبه 13 دی 1396, 08:56 صبح
خب تا اینجا پیش رفتم و درست عمل میکنه. فقط یه مشکل وجود داره وقتی موقع لود عکسها پنل رو که اسکرول میکنم اون row که تعریف کردم بهم میخوره.مثلا یه کم پایینتر میافته عکسا:متفکر:. ولی اگه اسکرول نکنم مشکلی پیش نمیاد. اینم راهنمایی کنید عالی میشه.



int row = 0;
int col = 0;
private BackgroundWorker _worker1;
string[] files;
int index = 0;
public GalleryFrm()
{
InitializeComponent();
}
Bitmap bmp = null;
private void GalleryFrm_Load(object sender, EventArgs e)
{
_worker1 = new BackgroundWorker();
_worker1.DoWork += new DoWorkEventHandler(worker1_DoWork);
_worker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_worker1_RunWorkerC ompleted);
AppSeetingClass.SetSetting();
files = Directory.GetFiles(@"D:\FileServer\Gallery");
if (files.Length > 0)
{
MessageBox.Show(files.Length.ToString());
startdowork();
}
}
public void startdowork()
{
if (index < files.Length)
{
_worker1.RunWorkerAsync(files[index]);
index++;
}
}

private void _worker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{

startdowork();

}

private void worker1_DoWork(object sender, DoWorkEventArgs e)
{
if (e.Argument.ToString().Substring(e.Argument.ToStri ng().Length - 2, 2) != "db")
{
bmp = new Bitmap(e.Argument.ToString());
var card = new PictureBox();
card.BackgroundImage = bmp;
card.Padding = new Padding(0);
card.BackgroundImageLayout = ImageLayout.Stretch;
//card.MouseDown += new MouseEventHandler(card_click);
card.Size = new Size(200, 200);
card.Left = col + 20;
card.Top = row;
if (col > 400)
{
col = 0;
row += 220;
}
else
col += 220;
CreateList(card);
}
}
private void CreateList(Control card)
{
if (this.InvokeRequired)
this.Invoke((Action<Control>)AddItem, card);
else
AddItem(card);
}
private void AddItem(Control card)
{
panel1.Controls.Add(card);
}



اینم تصویر بعد از اسکرول

parvizwpf
چهارشنبه 13 دی 1396, 09:19 صبح
اینطور مشکل ها نیاز به تریس داره که چرا اتفاق میافته . دلیلش رو منم نمیدونم