Creați un Wallview pentru imagini cu Silverlight Cod

Bine ați venit în partea a doua a creării unui Wallview inspirat de iTunes. În această parte vom scrie întregul cod în C # pentru cele două UserControls pe care le-am creat cu Expression Blend în tutorialul anterior.


Rezultatul final al rezultatelor

Luați o altă privire la demo-ul video al rezultatului final la care vom lucra (sau doar verificați demo-ul de mai sus):


Pasul 1: Deschideți Proiectul

Deschideți Visual Studio și faceți clic pe "File"> "Open"> "Project / Solution" din bara de meniu.

Apoi parcurgeți proiectul pe care l-am creat în prima parte a acestui tutorial. Am numit-o "WallviewApp".


Pasul 2: Deschideți Documentele C #

În partea dreaptă a Visual Studio este în mod implicit Solution Explorer. Aici puteți vedea fiecare fișier din proiect. Continuați și deschideți cele două fișiere * .cs "image.xaml.cs" și "wallview-img.xaml.cs" din cele două UserControls create în tutorialul anterior din Blend, precum și în "MainPage.xaml.cs" care au fost furnizate automat.

Odată ce ați deschis aceste trei fișiere, puteți observa că toate cele trei clase sunt destul de goale.


Pasul 3: Clasa imagine declară variabilele

Să începem cu codarea clasei de imagini. Asigurați-vă că editați fișierul "image.xaml.cs" și adăugați următoarele declarații chiar deasupra constructorului "public image ()":

 bool public selectat; private double defaultSize; privat wallview_img wallview; privat SolidColorBrush colorDefault, colorSelected;

Pasul 4: Clasa imaginii Scrieți constructorul

Acum vom programa constructorul care are doi parametri: BitmapImage și String. În plus, variabilele declarate anterior sunt inițializate, parametrii din constructor sunt atribuiți sursei "img" și textului de text "imgName". De asemenea, înregistrăm un eventhandler pentru evenimentul MouseLeftButtonDown al "img":

 imagine publică (BitmapImage src, Nume șir) // Necesită pentru a inițializa variabilele InitializeComponent (); selectat = fals; defaultSize = 200; colorDefault = noul SolidColorBrush (Color.FromArgb (0x00, 0x76, 0xA2, 0xF9)); colorSelected = nou SolidColorBrush (Color.FromArgb (0xFF, 0x76, 0xA2, 0xF9)); this.img.Source = src; this.imgName.TextAlignment = TextAlignment.Center; this.imgName.Text = nume; this.imgDate.TextAlignment = TextAlignment.Center; this.img.MouseLeftButtonDown + = nou MouseButtonEventHandler (image_MouseLeftButtonDown); 

Parametrul BitmapImage este subliniat cu o culoare roșie deoarece Visual Studio nu poate găsi spațiul de nume. Pentru a repara că faceți clic pe cuvântul BitmapImage și un mic dreptunghi albastru ar trebui să apară sub litera B:

Când deplasați mouse-ul peste micul dreptunghi, va apărea un meniu derulant. Faceți clic pe intrarea "Utilizând System.Windows.Media.Imaging;":

Acum Visual Studio știe că spațiul de nume, iar sublinierea roșie va dispărea.


Pasul 5: Codul de imagine Unele metode

Imediat după constructor vom scrie câteva metode pe care le vom avea nevoie mai târziu. Metodele sunt destul de auto-descriptive din numele metodelor lor. image_MouseLeftButtonDown este managerul evenimentului MouseLeftButtonDown evenimentul "img" pe care l-am înregistrat în constructor. Acesta controlează în principiu ceea ce se întâmplă când faceți clic pe imagine, în funcție de starea sa (dacă este selectată deja sau nu):

 public void setWallview (wallview_img wv) wallview = wv;  public void changeSize (dublu newsize) this.imgName.Width = defaultSize * newsize; this.imgSize.Width = defaultSize * newsize; this.imgSize.Height = defaultSize * newsize;  void public unselectImage () select = false; this.imgBorder.BorderBrush = colorDefault;  void public selectImage () select = true; this.imgBorder.BorderBrush = colorSelected;  privat void image_MouseLeftButtonDown (expeditor obiect, System.Windows.Input.MouseButtonEventArgs e) wallview.imageSelected = true; dacă (wallview.ctrlPressed == true) if (select == true) unselectImage (); altceva selectImage ();  altfel wallview.unselectAllImages (); selectImage ();  e.Handled = true; 

Acum am terminat cu clasa de imagini.

Nu vă faceți griji cu privire la părțile roșii subliniate din codul dvs. Aceste variabile și metode nu există încă și de aceea Visual Studio nu le cunoaște, dar vom schimba acest lucru în curând.


Pasul 6: Clasa de perete-img declară variabilele

Deoarece am terminat cu clasa de imagini, deschideți documentul "wallview-img.xaml.cs". La început scrieți declarațiile de variabile chiar deasupra constructorului "public wallview_img ()":

 Lista publică Imagelist; Lista privată panelistă; bool public ctrlPressed, imageSelected; private double defaultSize, changeSize;

La fel ca înainte cu Visual Studio BitmapImage nu cunoaște spațiul de nume al Listă. Pentru a remedia acest lucru, ca și înainte, dați clic pe una dintre liste, apoi pe dreptunghiul albastru și selectați "folosind System.Collections.Generic;" din meniu:


Pasul 7: Clasa de perete-img Codul Constructorului

Adăugați următorul cod care inițializează variabilele declarate anterior, înregistrează unele evenimente și dezactivează butoanele din bara de navigare:

 public wallview_img () // Necesar pentru inițializarea variabilelor InitializeComponent (); ctrlPressed = false; imageSelected = false; imageList = Listă nouă(); panelList = listă nouă(); defaultSize = 200; changeSize = 1; // înregistrarea tuturor evenimentelor MouseLeftButtonUp + = nou MouseButtonEventHandler (wallviewMouseLeftButtonUp); SizeChanged + = noul SizeChangedEventHandler (resizeScrollViewer); KeyDown + = noul KeyEventHandler (keyDownEvent); KeyUp + = noul KeyEventHandler (keyUpEvent); this.slider.ValueChanged + = nou RoutedPropertyChangedEventHandler(SliderValueChanged); // butoane nu avem nevoie încă de this.btnAllAlbums.IsEnabled = false; this.btnCurrentAlbum.IsEnabled = false; this.btnNext.IsEnabled = false; this.btnPrev.IsEnabled = false; 

Pasul 8: classview-img Class Scrieți metodele

Adăugați următoarele metode sub constructor. Comentariul înainte de fiecare metodă explică ce face metoda:

 // adaugă o imagine la imagelist și sună la resizeimages () care o adaugă practic la ultimul public stackpanel void addImage (image img) img.imgName.Width = 200; img.setWallview (aceasta); imageList.Add (img); resizeImages ();  // șterge întregul conținut desenat, fiecare panou, lista de albume și publicul panelist void clearLists () imageList.Clear (); foreach (StackPanel x în panelList) x.Children.Clear ();  this.content.Children.Clear (); panelList.Clear ();  // calculează câte stackpanels = rândurile sunt necesare public void updatePanels () if (imageList.Count> 0) foreach (StackPanel sp în panelList) sp.Children.Clear (); panelList.Clear (); grilă dublă = 0; dacă (this.content.ActualWidth == 0) gridWidth = 800; altceva gridWidth = this.content.ActualWidth; int gridWidthInt = Convert.ToInt32 (gridWidth); int imageAmount = imageList.Count; int imageMargin = 10; int imagineWidth = Convert.ToInt32 (implicitSize * changeSize); int imagineSize = imagineWidth + 2 * imagineMargin; raport dublu = gridWidth / (dublu) imageSize; int ratioInt = Convert.ToInt32 (raport); dacă (ratioInt - raport> 0) ratioInt - = 1; int newImageMargin = ((gridWidthInt - raportInt * imageWidth) / ratioInt) / 2; panou dubluAmountDouble = (dublu) imageAmount / ratioInt; int panoulAmountInt = (int) panelAmountDouble; dacă (panelAmountDouble - panelAmountInt> 0) panelAmountInt ++; dacă (panelAmountInt < 1) panelAmountInt = 1; int x = 0; for (int i = 0; i < panelAmountInt; i++)  StackPanel panel = new StackPanel(); panel.Orientation = Orientation.Horizontal; panel.Margin = new Thickness(0, 5, 0, 0); for (int j = 0; j < ratioInt; j++)  if (x < imageAmount)  imageList[x].Margin = new Thickness(newImageMargin, 0, newImageMargin, 10); imageList[x].changeSize(changeSize); imageList[x].setWallview(this); panel.Children.Add(imageList[x]);  x++;  panelList.Add(panel);    //selects all images, gets called when ctrl + a is pressed public void selectAllImages()  foreach (image i in imageList) i.selectImage();  //unselects all iamges public void unselectAllImages()  foreach (image i in imageList) i.unselectImage();  //gets called when the slider value changes private void resizeImages()  updatePanels(); this.content.Children.Clear(); foreach (StackPanel sp in panelList) this.content.Children.Add(sp);  //method gets called by the slidervaluechanged event public void changeImageSize(double newsize)  changeSize = newsize; resizeImages(); 

Pasul 9: Wallview-img Classhandlers de clasă

În acest pas, scriem eventualele manipulatoare de evenimente pentru evenimentele pe care le-am înregistrat mai devreme în constructor:

 // eventhandler pentru când slider-ul se schimbă privat void sliderValueChanged (sender obiect, System.Windows.RoutedPropertyChangedEventArgs e) dimensiune changeImageSize (aceasta.slider.Value);  // eventhandler care devine apelat atunci când ferestrele modifică privat void resizeScrollViewer (expeditor obiect, System.Windows.SizeChangedEventArgs e) resizeImages ();  // eventhandler care selectează toate imaginile când nu dați clic pe o imagine void wallviewMouseLeftButtonUp (expeditor obiect, MouseButtonEventArgs e) if (! imageSelected) unselectAllImages (); altceva imageSelected = false;  // eventhandler pentru apăsarea tastelor private void keyDownEvent (expeditor obiect, System.Windows.Input.KeyEventArgs e) if (e.Key == Key.Ctrl) ctrlPressed = true; altceva dacă (e.Key == Key.A) dacă (ctrlPressed) selectAllImages ();  // eventhandler pentru eliberarea cheilor private void keyUpEvent (sender de obiecte, System.Windows.Input.KeyEventArgs e) if (e.Key == Key.Ctrl) ctrlPressed = false; 

Acum am terminat cu wallview-img clasă. Să continuăm cu crearea unei web servicii pe care o vom avea nevoie pentru Pagina principală clasă.


Pasul 10: Creați o Webservice

Webservice pe care o vom scrie în esență ne oferă imaginile dintr-un anumit dosar. Pentru a crea un serviciu web, faceți clic dreapta pe "WallviewApp.Web" în Solution Explorer din partea dreaptă a Visual Studio și selectați "Add"> "New Item" din meniu:

Din meniul pop-up selectați "Service-ul WCF activat de Silverlight Visual C #" și introduceți "WCF.svc" pentru un nume, apoi faceți clic pe "Adăugați":

După cum puteți vedea, am obținut o altă clasă numită WCF cu propriul document de cod, "WCF.svc.cs".


Pasul 11: Cod de clasă WCF Două metode

Adăugați următoarele două metode în clasa WCF chiar sub linia care spune "// Adăugați mai multe operații aici și marcați-le cu [OperationContract]„:

 // metoda pentru obținerea tuturor numelor de fișiere dintr-un folder [OperationContract] șir public [] getFileNames (String dir) încercare String tmp = HttpContext.Current.Request.MapPath (dir); retur directorul.GetFiles (@tmp, "* .jpg");  captură (excepție) return null;  // metoda care returnează data creării unui fișier sau a unui dosar [OperationContract] public String getFileDates (fișier String, int i) returnați i.ToString () + "-" + File.GetLastWriteTime (fișier) .ToString ); 

Remediați spațiile de nume lipsă așa cum am făcut mai devreme făcând clic pe numele afectate, apoi pe dreptunghiul albastru și pe "import ..." sau adăugând manual aceste două linii în partea de sus a documentului:

 utilizând System.Web; utilizând System.IO;

Pasul 12: Referința serviciului Partea 1

Pentru a putea utiliza serviciul web, trebuie să adăugăm o referință de service la proiectul principal. Înainte de a putea face acest lucru, trebuie să construim o dată proiectul. Prin urmare, faceți clic pe "Construiți" din meniul din partea superioară a Visual Studio și apoi pe "Build WallviewApp":


Pasul 13: Referința serviciului Partea 2

După ce ați reușit construirea, faceți clic dreapta pe "WallviewApp" din partea dreaptă a Solution Explorer și alegeți "Add Service Reference" din meniu:


Pasul 14: Referința serviciului Partea 3

În fereastra pop-up, faceți clic pe butonul "Descoperă" și introduceți "WCFRef" în câmpul Nume spațiu, apoi faceți clic pe "OK":

Fără construirea proiectului înainte de a încerca să adăugați o referință de service, ați fi primit acest mesaj de eroare:


Pasul 15: Clasa MainPage declară variabilele

Deschideți fișierul "MainPage.xaml.cs" și adăugați următoarele linii de cod deasupra constructorului "public MainPage ()„:

 client privat WCFRef.WCFClient; string privat imagedir = "/ image /"; public wallview_img wvi; private int amountImages;

Pasul 16: Clasa MainPage Programați constructorul

Constructorul Pagina principală arata asa. Inițializăm declarațiile de la pasul anterior, înregistrăm manualele de evenimente ale webservicii și adăugăm wallview_img numit "wvi"la Grilă "LayoutRoot"din Pagina principală:

 public MainPage () InitializeComponent (); amountImages = 0; client = nou WallviewApp.WCFRef.WCFClient (); client.getFileNamesCompleted + = nou EventHandler(Client_getFileNamesCompleted); client.getFileNamesAsync (imagedir); client.getFileDatesCompleted + = nou EventHandler(Client_getFileDatesCompleted); wvi = noul wallview_img (); this.LayoutRoot.Children.Add (wvi); 

Pasul 17: Codificați Eventhandlers pentru Webservice

Adăugați următoarele două aplicații pentru evenimente și metoda de sub constructorul MainPage.

""client_getFileNamesCompleted ()"primește o serie de șiruri de caractere care sunt returnate de webservice. Matricea este transformată în șiruri separate de la care este extras numele fișierului.

Utilizarea gazdă locală adresa, portul, directorul imagine și numele fișierului, construim un uri numit "src". Acea uri este folosit pentru a crea un nou BitmapImage "bmi" care este necesar pentru a crea o imagine nouă "tmp". Apoi, imaginea "tmp" se adaugă la wallview_img "WMI".

Ulterior, metoda care returnează data creării unui fișier este apelată împreună cu un număr de contor. Orice metodă returnează această metodă este procesată de handlerul "client_getFileDatesCompleted ()". Deoarece un șir în format > 2-18.02.2009 12:32:23 este returnat de pe webservice, trebuie sa despartim numarul contorului la inceput si data la mijloc.

Când această procedură este finalizată, data finală arată > 18.02.2009 și i se atribuie Textblock "imgDate" a imaginii corespunzătoare.

 // handler de evenimente pentru obținerea numelor de fișiere din folderul void privat client_getFileNamesCompleted (sender de obiecte, WallviewApp.WCFRef.getFileNamesCompletedEventArgs e) if (e.Result! = null) foreach (șir s în e.Result) int pos = s.LastIndexOf ( "\\"); string nume fișier = s.Substring (pos + 1); int port = Application.Current.Host.Source.Port; Uri src = nou Uri ("http: // localhost:" + port + imagedir + nume fișier); BitmapImage bmi = BitmapImage nou (src); imagine tmp = imagine nouă (bmi, nume de fișier); this.wvi.addImage (tmp); amountImages ++; getFileDate (s, amountImages - 1);  altceva MessageBox.Show ("returnat null în fișiere finalizate");  // metoda care asociaza asincrona webservice cu un șir de fișiere și un număr, astfel încât să putem asocia șirul de date returnat unei anumite imagini din nou void privat getFileDate (String s, int i) this.client.getFileDatesAsync (s, i );  // manipulator de evenimente pentru a obține void privat filedates client_getFileDatesCompleted (expeditor obiect, WallviewApp.WCFRef.getFileDatesCompletedEventArgs e) if (e.Result! = null) String dt = e.Result; int numărul = Convert.ToInt32 (dt.Remove (dt.LastIndexOf ("-"))); Data șirului = dt.Remove (dt.LastIndexOf (")); dacă (numărul < 10) date = date.Remove(0, 2); else if (number < 100) date = date.Remove(0, 3); else date = date.Remove(0, 4); this.wvi.imageList[number].imgDate.Text = date;  else  MessageBox.Show("returned null in dates completed");  

Ca și în celelalte surse, spațiul de nume "BitmapImage" nu poate fi găsit. Pentru a repara acest lucru, faceți clic pe dreptunghiul albastru și îl importați după ce faceți clic pe textul din BitmapImage, sau adăugați manual linia următoare în partea de sus a documentului:

 utilizând System.Windows.Media.Imaging;

Pasul 18: Rulați Proiectul

Continuați și executați proiectul pentru a vedea dacă totul funcționează. Puteți face acest lucru fie prin apăsarea butonului "F5" de pe tastatură, făcând clic pe butonul cu o pictogramă tipică "Play" sub meniul din partea de sus a barei de pictograme, fie selectând intrarea "Debugging Start" din "Debug" submeniul din meniul din partea superioară a Visual Studio:

Browserul dvs. se deschide și veți primi acest mesaj de eroare:

Care este problema?

Am spus webservicii să verifice folderul "http: // localhost: port / image /" pentru fișierele * .jpg și, evident, nici dosarul și nici imaginile din folderul respectiv nu există încă.


Pasul 19: Pregătiți folderul imagine

Navigați la directorul de proiect cu Windows Explorer. Pentru mine este următoarea cale:

Deschideți dosarul "WallviewApp.Web" și creați un nou folder denumit "imagine" în interiorul acestuia.

Acum, deschideți directorul "imagine" și lipiți câteva imagini * .jpg în el.


Pasul 20: Rulați din nou proiectul

Odată ce ați plasat câteva imagini în interiorul directorului imagine, fie apăsați refresh în interiorul webbrowser-ului dvs. (dacă acesta este încă deschis), fie pur și simplu executați din nou proiectul apăsând tasta "F5" din Visual Studio. Ca urmare, ar trebui să vedem ultimul nostru WallView:

Puteți influența dimensiunea imaginilor afișate cu glisorul din bara de navigare.


Concluzie

Am terminat de acum cu acest tutorial și sper că v-ați bucurat și ați învățat ceva.

Timpul aproximativ total pe care mi-a luat-o pentru a dezvolta acest lucru de la zero a fost de aproximativ 20 de ore. Imaginea de pe perete pentru albume pe care o puteți vedea în videoclipul de mai jos mi-a luat aproximativ 15 ore și alte 10 ore pentru a combina tipurile de perete.

S-ar putea să vă întrebați ce este punctul de a putea selecta una sau mai multe imagini. Chiar acum această funcționalitate este inutilă, dar mi-aș putea imagina adăugarea posibilității de a începe o prezentare de diapozitive sau de a crea un playlist de la imaginile selectate, de exemplu. Și dacă vă întrebați de ce am adăugat butoanele "Toate albumele", "Albumul curent", "<" and ">"în bara de navigare, dar nu le-a folosit niciodată ...

Intenția mea este să dezvolt un alt tutorial care generează automat albume foto bazate pe numele de fișiere ale imaginilor. Desigur, acest tutorial va extinde proiectul din tutorialul pe care tocmai l-ați completat aici. Aș fi vrut cu siguranță să fac asta dacă este popular cu audiența. Pentru a obține o imagine a ceea ce ar arăta imaginea de perete pentru imagini pe care tocmai am creat-o în combinație cu o vizualizare de perete pentru albume foto, consultați următorul videoclip:

Pentru orice comentarii, sugestii sau preocupări, lăsați o notă în secțiunea de comentarii. Vă mulțumim pentru lectură!

Cod