Prilikom odabira foldera startujemo metodu za učitavanje slika i tajmer u novim thread-ovima.
Code:
private void btnUcitaj_Click(object sender, RoutedEventArgs e)
{
System.Windows.Forms.FolderBrowserDialog dlg = new System.Windows.Forms.FolderBrowserDialog();
System.Windows.Forms.DialogResult result = dlg.ShowDialog();
if (result == System.Windows.Forms.DialogResult.OK)
{
Ucitao = false;
string IzabraniFolder = dlg.SelectedPath;
string[] fajlovi = System.IO.Directory.GetFiles(IzabraniFolder, "*", System.IO.SearchOption.TopDirectoryOnly);
BrSlika = fajlovi.Length;
AsyncMethodHandler caller = default(AsyncMethodHandler);
caller = new AsyncMethodHandler(UcitajSlike);
caller.BeginInvoke(fajlovi, UcitaoSam, null);
System.Threading.Thread thr1 = new System.Threading.Thread(
new System.Threading.ThreadStart(KreirajIStartujTajmer));
thr1.Start();
}
}
Što se tiče tajmera, njega instanciramo i startujemo, a on prilikom svakog odbrojavanja proveri da li su slike učitane, i
ažurira labelu i progresnu liniju pozivajući metodu iz glavnog thread-a.
Code:
void KreirajIStartujTajmer()
{
tajmer = new System.Timers.Timer(100);
tajmer.Elapsed += new System.Timers.ElapsedEventHandler(tajmer_Elapsed);
tajmer.Start();
}
void tajmer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
tajmer.Stop();
if (Ucitao)
{
BrTekuceSlike = BrSlika;
}
else
{
tajmer.Start();
}
UpdatePrgBarILbl();
}
private void UpdatePrgBarILbl()
{
if (prgBar.Dispatcher.CheckAccess())
{
double vr = 100 * (double)BrTekuceSlike / (double)BrSlika;
prgBar.SetValue(ProgressBar.ValueProperty, vr);
lblVreme.Content = DateTime.Now.Hour.ToString() + ":" + DateTime.Now.Minute.ToString() + ":" +
DateTime.Now.Second.ToString() + " - " + (String.Format("{0:0}", vr)).ToString() + "%";
}
else
{
prgBar.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal,
new PrgBarUpdate(UpdatePrgBarILbl));
}
}
Učitavanje slika se vrši jednim delom u novom thread-u, a drugim delom u osnovnom UI thread-u.
Bilo bi dobro da može da se iz drugog thread-a, kao parametar funkcije, vrati čitav niz Image-a, ali
nije mi to pošlo za rukom.
U svakom slučaju, ovde se pripremi niz bajtova koji se šalje sa ostalim parametrima u novu metodu.
Code:
private bool UcitajSlike(string[] fajlovi)
{
bool UcitaoBezProblema = true;
try
{
System.IO.FileInfo fi;
for (BrTekuceSlike = 0; BrTekuceSlike < BrSlika; BrTekuceSlike++)
{
fi = new System.IO.FileInfo(fajlovi[BrTekuceSlike]);
if (fi.Extension == ".JPG")
{
Byte[] ByteArray;
FileStream fs = new FileStream(fajlovi[BrTekuceSlike], FileMode.Open);
using (BinaryReader br = new BinaryReader(fs))
{
ByteArray = br.ReadBytes(Convert.ToInt32(fs.Length));
}
lvSlicice.Dispatcher.Invoke(new DodavanjeUNiz(DodajElemUNiz),
System.Windows.Threading.DispatcherPriority.Normal,
new object[] { fajlovi[BrTekuceSlike], BrTekuceSlike, ByteArray });
}
if (BrTekuceSlike == BrSlika - 1) { Ucitao = true; }
}
}
catch
{
UcitaoBezProblema = false;
}
return UcitaoBezProblema;
}
Ova metoda (DodajElemUNiz) se startuje iz osnovnog UI thread-a.
Code:
private void DodajElemUNiz(string fajl, int RBr, Byte[] ByteArray)
{
BitmapImage Slicica = new BitmapImage();
Slicica.BeginInit();
Slicica.UriSource = new Uri(fajl);
Slicica.StreamSource = new System.IO.MemoryStream(ByteArray);
Slicica.DecodePixelWidth = 200;
Slicica.EndInit();
ImageSource imgsrc = (ImageSource)Slicica;
Image img = new Image();
img.Source = imgsrc;
lvSlicice.Items.Add(img);
}
Na kraju, kada se završi učitavanje svih slika, izvršava se metoda UcitaoSam jer je naznačena
kao callback metoda prilikom pozivanja metode UcitajSlike.
Code:
private void UcitaoSam(IAsyncResult ar)
{
AsyncResult result = (AsyncResult)ar;
AsyncMethodHandler caller = (AsyncMethodHandler)result.AsyncDelegate;
bool returnValue = caller.EndInvoke(ar);
Ucitao = true;
}
Ovde podižemo flag Ucitao = true, tako da tajmer prekida svoj rad.
U ovom primeru nedostaje postavljanje podrazumevanih vrednosti na kraju učitavanja i prilikom
ponovnog klika na button, rad sa slikama drugih ekstenzija, enable-ovanje i disable-ovanje button-a
i mnogo šta drugo, ali ovo je samo primer.
Evo i deklaracija ...
Code:
private delegate void Tajmer();
private delegate void PrgBarUpdate();
private delegate void DodavanjeUNiz(string fajl, int RBr, Byte[] ByteArray);
delegate bool AsyncMethodHandler(string[] fajlovi);
delegate void PopuniListuHandler(bool ImgSrcList);
Image[] NizSlicica = new Image[] { };
private Image img = new Image();
private System.Timers.Timer tajmer;
private bool Ucitao;
private int BrSlika = 0;
private int BrTekuceSlike = 0;
... i XAML-a
Code:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="40"></RowDefinition>
<RowDefinition Height="40"></RowDefinition>
<RowDefinition Height="40"></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<ListView Name="lvSlicice" Grid.Row="0" Grid.RowSpan="4"></ListView>
<Button Name="btnUcitaj" Grid.Row="0" Grid.Column="1" Click="btnUcitaj_Click">Učitaj</Button>
<Label Name="lblVreme" Grid.Row="1" Grid.Column="1"></Label>
<ProgressBar Name="prgBar" Grid.Row="2" Grid.Column="1"></ProgressBar>
</Grid>
Da bi kod radio, mora još da se doda i referenca na Szstem.Windows.Forms.
Pozdrav.