рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ xkcd рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ C # рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рд╡реЗрдм рдХреЙрдорд┐рдХ рд╕реЗ рдПрдХ рдкреАрдбреАрдПрдл рдкреБрд╕реНрддрдХ рдмрдирд╛рдирд╛

рд╕реЛрдиреА PRS-650 рдФрд░ xkcd рдирдИ xkcd рд░рд┐рд▓реАрдЬрд╝ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реБрдП, рдореИрдВрдиреЗ рдЕрдкрдиреЗ рддрд╛рдЬрд╝рд╛ рдЦрд░реАрджреЗ рд╕реЛрдиреА PRS-650 рдЗрд▓реЗрдХреНрдЯреНрд░рд┐рдХ рдмреБрдХ рдХреЛ рджреЗрдЦрд╛, рдФрд░ рддреБрд░рдВрдд рд╕реЛрдЪрд╛ - рдореИрдВ рдЗрд╕ рдкрд░ рдХреЙрдорд┐рдХреНрд╕ рджреЗрдЦрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдБ! Xkcd рд╕рд┐рд░реНрдл рдХрд╛рд▓реЗ рдФрд░ рд╕рдлрд╝реЗрдж рд╣реИрдВ рдФрд░ рдЖрдорддреМрд░ рдкрд░ рдЖрдХрд╛рд░ рдореЗрдВ рдЫреЛрдЯреЗ рд╣реИрдВред рдереЛрдбрд╝рд╛ рд╕рд╛ Google, рдХреЗрд╡рд▓ TPB рдкрд░ рдЫрд╡рд┐рдпреЛрдВ рдХрд╛ рдПрдХ рд╕рдВрдЧреНрд░рд╣ рдкрд╛рдпрд╛, рдФрд░ bash рдкрд░ рдПрдХ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЬреЛ рдкреАрдбреАрдПрдл рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдореИрдВрдиреЗ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдореЗрдВ рдереЛрдбрд╝рд╛ рдордЬрд╝рд╛ рд▓реЗрдиреЗ рдФрд░ рдЕрдкрдиреЗ рдкрд╕рдВрджреАрджрд╛ C # рдореЗрдВ рдПрдХ рдХреЙрдорд┐рдХ рдмреБрдХ рдЧреНрд░реИрдмрд░ рдмрдирд╛рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ред



рдХрдВрд╕реЛрд▓ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рд╕рд╛рде рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди, рд╕реНрдкрд╖реНрдЯрддрд╛ рдХреЗ рд▓рд┐рдП, WPF рдкрд░ рдПрдХ рд╕рд░рд▓ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред





рдХреЛрдб рдХрд╛ рдПрдХ рдкреВрд░реНрдг рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдмреЗрдорд╛рдиреА рд╣реЛрдЧрд╛, рдЗрд╕рд▓рд┐рдП рдореИрдВ рдореБрдЦреНрдп рдмрд┐рдВрджреБрдУрдВ рдХреЛ рд╕рдордЭрд╛рдКрдВрдЧрд╛ред рдореИрдВ рддреБрд░рдВрдд Google рдХреЛрдб рд╕реЗ рдкреВрд░реНрдг рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛрдб рдЦреЛрд▓рдиреЗ / рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВред











1. рд╕рд╛рдЗрдЯ рд╕реЗ рдЪрд┐рддреНрд░, рд╢реАрд░реНрд╖рдХ рдФрд░ рдСрд▓реНрдЯ-рдЯреЗрдХреНрд╕реНрдЯ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ



Xkcd рдкрд░, рдХреЙрдорд┐рдХреНрд╕ рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд░реВрдк рдореЗрдВ xkcd.com/n рдХреЗ рдкрддреЗ рдкрд░ рд╕реНрдерд┐рдд рд╣реИ, рдЬрд╣рд╛рдБ n = 1 ...

рдкрд╣рд▓рд╛ рд╡рд┐рдЪрд╛рд░ рдкреЗрдЬ рдХреЛрдб рд╕реЗ рд╕рд╣реА рдХреЛ рдлрд╛рдбрд╝рдирд╛ рдерд╛, рд▓реЗрдХрд┐рди рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рдХрд┐ рдЖрдк рдлреЙрд░реНрдо Jkcd.com {0} /info.0.json рдХреЗ рдкрддреЗ рдкрд░ JSON рдореЗрдВ рд╕рднреА рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред



.NET рдореЗрдВ JSON рдХреЗ рд▓рд┐рдП, рдПрдХ DataContractJsonSerializer рд╣реИ

рдЙрдЪрд┐рдд рдбреЗрдЯрд╛ рдХреНрд░реИрдХрдЯреНрд░реЗрдХреНрдЯ рдмрдирд╛рдПрдБ:



[DataContract] public class XkcdComic { #region Public properties and indexers [DataMember] public string img { get; set; } [DataMember] public string title { get; set; } [DataMember] public string month { get; set; } [DataMember] public string num { get; set; } [DataMember] public string link { get; set; } [DataMember] public string year { get; set; } [DataMember] public string news { get; set; } [DataMember] public string safe_title { get; set; } [DataMember] public string transcript { get; set; } [DataMember] public string day { get; set; } [DataMember] public string alt { get; set; } #endregion }
      
      







... рдФрд░ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ:

  private static XkcdComic GetComic(string url) { var stream = new WebClient().OpenRead(url); if (stream == null) return null; var serializer = new DataContractJsonSerializer(typeof (XkcdComic)); return serializer.ReadObject(stream) as XkcdComic; }
      
      







Xkcd.com/info.0.json рдкрд░, рдЖрдк рдирд╡реАрдирддрдо рдХреЙрдорд┐рдХ рдмреБрдХ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдЕрдВрдХ рдХреНрд╖реЗрддреНрд░ рд╕реЗ рдЙрд╕рдХрд╛ рдирдВрдмрд░ рд▓реЗрддреЗ рд╣реБрдП, рдЙрдирдХреА рдХреБрд▓ рд╕рдВрдЦреНрдпрд╛ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛ рд╕рдХрддреЗ рд╣реИрдВред

рдпрд╣ рдЪрд┐рддреНрд░ рдХреЛ рд╣реА рдЦрд╝рд░рд╛рдм рдХрд░рдирд╛ рд╣реИ, рд╕рдм рдХреБрдЫ рд╕рд░рд▓ рд╣реИ:

 var imageBytes = WebRequest.Create(comicInfo.img).GetResponse().GetResponseStream().ToBytes();
      
      





... рдЬрд╣рд╛рдБ comicInfo JSON рд╕реЗ рд╣рдорд╛рд░рд╛ рдбреЗрдЯрд╛ рд╣реИ, рдФрд░ ToBytes () рдПрдХ рд╕рд░рд▓ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд╡рд┐рдзрд┐ рд╣реИ рдЬреЛ рдХрд┐рд╕реА рд╕реНрдЯреНрд░реАрдо рд╕реЗ рдбреЗрдЯрд╛ рдХреЛ рдПрдХ рдЕрд░реИ рдореЗрдВ рдкрдврд╝рддрд╛ рд╣реИред



рдХреЙрдорд┐рдХ рд╕реНрдЯреНрд░рд┐рдк (рдХреЙрдорд┐рдХ рд╕реНрдЯреНрд░рд┐рдк, рдпрд╛ рдЗрд╕реЗ рдПрдХрд╡рдЪрди рдореЗрдВ рд╕рд╣реА рддрд░реАрдХреЗ рд╕реЗ рдХреИрд╕реЗ рдХреЙрд▓ рдХрд░реЗрдВ?) рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдХреЙрдорд┐рдХ рдХреНрд▓рд╛рд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рддрд╕реНрд╡реАрд░ рдХреЗ рдкреНрд░рд╛рдкреНрдд рдмрд╛рдЗрдЯреНрд╕ рдХреЛ рдорд╛рдиреНрдп рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП (рдФрд░ рд╣рдо рдХреБрдЫ рдЧрд▓рдд рдбрд╛рдЙрдирд▓реЛрдб рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд╕рд░реНрд╡рд░ рдПрдХ рддреНрд░реБрдЯрд┐, рдЖрджрд┐ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░ рд╕рдХрддрд╛ рд╣реИ) рдХреНрд▓рд╛рд╕ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдХреЛ рдирд┐рдЬреА рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рдерд╛, рдФрд░ рдлрд╝реИрдХреНрдЯрд░реА рдмрдирд╛рдПрдБ рд╡рд┐рдзрд┐ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рдерд╛, рдЬреЛ рдПрдХ рдбрд┐рдХреЛрдбрд┐рдВрдЧ рддреНрд░реБрдЯрд┐ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рд╢реВрдиреНрдп рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рдПрдЧреАред BitmapImage рдХрд╛ рдЙрдкрдпреЛрдЧ рдбрд┐рдХреЛрдбрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рд╕рдлрд▓ рд╣реЛрдиреЗ рдкрд░ рдкрд░рд┐рдгрд╛рдо рдХреЛ рдкреВрд░реНрд╡рд╛рд╡рд▓реЛрдХрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдердВрдмрдиреЗрд▓ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛:

  public static Comic Create(byte[] imageBytes) { try { // Validate image bytes by trying to create a Thumbnail. return new Comic {ImageBytes = imageBytes}; } catch { // Failure, cannot decode bytes return null; } } public byte[] ImageBytes { get { return _imageBytes; } private set { _imageBytes = value; var bmp = new BitmapImage(); bmp.BeginInit(); bmp.DecodePixelHeight = 100; // Do not store whole picture bmp.StreamSource = new MemoryStream(_imageBytes); bmp.EndInit(); bmp.Freeze(); Thumbnail = bmp; } }
      
      







рдпрд╣ рд╕рдм рдПрдХ рд╕рд╛рде рд░рдЦрдХрд░, рд╣рдореЗрдВ рдПрдХ рдХреЙрдореЗрдбрд┐рдпрди рд╕реНрдЯреНрд░рд┐рдк рдХреЛ рдЙрд╕рдХреЗ рдирдВрдмрд░ рд╕реЗ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рдиреЗ рдХреА рд╡рд┐рдзрд┐ рдорд┐рд▓рддреА рд╣реИ:

  protected override Comic GetComicByIndex(int index) { // Download comic JSON var comicInfo = GetComic(string.Format(UrlFormatString, index + 1)); if (comicInfo == null) return null; // Download picture var imageStream = WebRequest.Create(comicInfo.img).GetResponse().GetResponseStream().ToMemoryStream(); var comic = Comic.Create(imageStream.GetBuffer()); if (comic == null) return null; comic.Description = comicInfo.alt; comic.Url = comicInfo.link; comic.Index = index + 1; comic.Title = comicInfo.title; // Auto-rotate for best fit var t = comic.Thumbnail; if (t.Width > t.Height) { comic.RotationDegrees = 90; } return comic; }
      
      







рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХрдИ рдХреЙрдорд┐рдХреНрд╕ рд╣реИрдВ рдФрд░ рд╕реВрдЪрдХрд╛рдВрдХ рджреНрд╡рд╛рд░рд╛ рдПрдХ рдкрдЯреНрдЯреА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдПрдХ рд╡рд┐рдзрд┐ рд╣реИред



рдбрд╛рдЙрдирд▓реЛрдб рдХрд╛ рд╕рдорд╛рдирд╛рдВрддрд░рдХрд░рдг



рдореИрдВ рдЯрд╛рд╕реНрдХ рдкреИрд░реЗрд▓рд▓ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реВрдВрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдореИрдВ рд▓рдВрдмреЗ рд╕рдордп рд╕реЗ рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рдерд╛, рд▓реЗрдХрд┐рди рдХреЛрдИ рдХрд╛рд░рдг рдирд╣реАрдВ рдерд╛ред рдкрд╣рд▓реА рдирдЬрд╝рд░ рдореЗрдВ, рд╕рдм рдХреБрдЫ рд╕рд░рд▓ рд╣реИ, рдПрдХ рд▓реВрдк рдореЗрдВ, рд╕реАрдзреЗ GetComicByIndex (i) рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп, рд╣рдо var рдЯрд╛рд╕реНрдХ рдХрд░рддреЗ рд╣реИрдВ = Task.Factory.StartNew (() => GetComicByIndex (i)ред рд╣рдо рд╕рднреА рд░рдирд┐рдВрдЧ рдЯрд╛рд╕реНрдХ рдХреЛ рдлрдВрдХреНрд╢рди рдРрд░реЗ рдореЗрдВ рд▓рд┐рдЦрддреЗ рд╣реИрдВ рдФрд░ рдЯрд╛рд╕реНрдХ рдХрд░рддреЗ рд╣реИрдВред AitAll (рдЯрд╛рд╕реНрдХ), рдЬрд┐рд╕рдХреЗ рдмрд╛рдж рд╣рдореЗрдВ рдЯрд╛рд╕реНрдХ рд╕реЗ рд╣рд░ рдЯрд╛рд╕реНрдХ рдХреЗ рд░рд┐рдЬрд▓реНрдЯ рдорд┐рд▓рддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╣рдореЗрдВ рдкреНрд░рдЧрддрд┐ рдХреЛ рдЯреНрд░реИрдХ рдХрд░рдиреЗ рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдкрд╣рд▓реЗ рд╕реЗ рд▓реЛрдб рд╕реНрдЯреНрд░рд┐рдкреНрд╕ рджрд┐рдЦрд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрдЧрд╛ред рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо WaitAny рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ рдФрд░ рдкреВрд░рд╛ рд╣реЛрдиреЗ рдкрд░ рдкреНрд░рддреНрдпреЗрдХ рдХрд╛рд░реНрдп рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдЬ рд▓реМрдЯрд╛рдПрдВрдЧреЗ:

  public IEnumerable<Comic> GetComics() { var count = GetCount(); var tasks = Enumerable.Range(0, count).Select(GetTask).ToList(); while (tasks.Count > 0) // Iterate until all tasks complete { var task = tasks.WaitAnyAndPop(); if (task.Result != null) yield return task.Result; } }
      
      







рдпрд╣рд╛рдВ, GetTask рд╡рд┐рдзрд┐ GetComicByIndex (i) рдХрд╛рд░реНрдп, рдкреНрд▓рд╕ рддреНрд░реБрдЯрд┐ рд╣реИрдВрдбрд▓рд┐рдВрдЧ рдФрд░ рдХреИрд╢рд┐рдВрдЧ рд▓реМрдЯрд╛рддреА рд╣реИ (рдпрд╣ рдЗрд╕ рдЖрд▓реЗрдЦ рдХреЗ рджрд╛рдпрд░реЗ рд╕реЗ рдкрд░реЗ рд╣реИ)ред WaitAnyAndPop рдПрдХ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд╡рд┐рдзрд┐ рд╣реИ, рдЬреЛ рдХрд┐рд╕реА рдПрдХ рдХрд╛рд░реНрдп рдХреЗ рдкреВрд░рд╛ рд╣реЛрдиреЗ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рддреА рд╣реИ, рдЙрд╕реЗ рд╕реВрдЪреА рд╕реЗ рд╣рдЯрд╛ рджреЗрддреА рд╣реИ, рдФрд░ рд╡рд╛рдкрд╕ рдХрд░ рджреЗрддреА рд╣реИ:

 WaitAnyAndPop тАФ extension ,      ,      : public static Task<T> WaitAnyAndPop<T>(this List<Task<T>> taskList) { var array = taskList.ToArray(); var task = array[Task.WaitAny(array)]; taskList.Remove(task); return task; }
      
      







рдЕрдм ViewModel рдХреЛрдб рдореЗрдВ (рдореИрдВ рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рд╡рд╛рд╕реНрддреБ рд╕рдВрдмрдВрдзреА рдореБрджреНрджреЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдирд╣реАрдВ рдХрд░рддрд╛, рд▓реЗрдХрд┐рди MVVM (рдореЙрдбрд▓-рд╡реНрдпреВ-рд╡реНрдпреВрдореЙрдбрд▓) WPF рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдорд╛рдирдХ рд╣реИ, рдФрд░ рдмреЗрд╢рдХ, рдирд┐рд░реНрдпрд╛рдд рдФрд░ рдЕрдиреНрдп рдЪреАрдЬреЛрдВ рдХреЗ рд▓рд┐рдП рдХреЛрдб, рд╕рдВрдмрдВрдзрд┐рдд рдХрдХреНрд╖рд╛рдУрдВ рдореЗрдВ рдЯреВрдЯ рдЧрдпрд╛ рд╣реИ) рд╣рдо GetComics рд╡рд┐рдзрд┐ рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдкреГрд╖реНрдарднреВрдорд┐ рд╕реНрдЯреНрд░реАрдо рдореЗрдВ рдкреБрдирд░рд╛рд╡реГрддрд┐ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реНрдЯреНрд░рд┐рдкреНрд╕ рдХреЛ рджрд┐рдЦрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдЬреИрд╕реЗ рд╡реЗ рдЖрддреЗ рд╣реИрдВ:

  private readonly Dispatcher _dispatcher; private readonly ObservableCollection<Comic> _comics = new ObservableCollection<Comic>(); private void StartGrabbing() { _dispatcher = Dispatcher.CurrentDispatcher; // ObservableCollection modifications should be performed on the UI thread ThreadPool.QueueUserWorkItem(o => DoGrabbing()); } private void DoGrabbing() { var grabber = new XkcdGrabber(); foreach (var comic in grabber.GetComics()) { var c = comic; _dispatcher.Invoke((Action) (() => Comics.Add( c )), DispatcherPriority.ApplicationIdle); } }
      
      







2. WPF рдореЗрдВ рдХреЙрдорд┐рдХреНрд╕ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдВ



XAML рдХреЛрдб рдореЗрдВ, рд╣рдо рдХреЗрд╡рд▓ рдЕрдкрдиреЗ рдСрдмреНрдЬрд░реНрд╡реЗрдмрд▓ рдХреЙрд▓реЗрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдмрд╛рдЗрдВрдбрд┐рдВрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдЯреВрд▓рдЯрд┐рдк рдореЗрдВ рдСрд▓реНрдЯ рдЯреЗрдХреНрд╕реНрдЯ рдХреЗ рд╕рд╛рде рд▓реЛрдбрд┐рдВрдЧ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдФрд░ рдХреЙрдорд┐рдХреНрд╕ рдХреЛ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдВрдмрдВрдзрд┐рдд DataTemplate рддреИрдпрд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

  <ListView ItemsSource="{Binding Comics}" ScrollViewer.VerticalScrollBarVisibility="Disabled" x:Name="list" Margin="5,0,5,0" ScrollViewer.HorizontalScrollBarVisibility="Visible" Grid.Row="1"> <ItemsControl.ItemTemplate> <DataTemplate> <Border BorderBrush="Gray" CornerRadius="5" Padding="5" Margin="5" BorderThickness="1"> <StackPanel Orientation="Vertical"> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding Index}" FontWeight="Bold" /> <TextBlock Text="{Binding Title}" FontWeight="Bold" Margin="10,0,0,0" /> </StackPanel> <Image Source="{Binding Thumbnail}" ToolTip="{Binding Description}" Height="{Binding Thumbnail.PixelHeight}" Width="{Binding Thumbnail.PixelWidth}" /> </StackPanel> </Border> </DataTemplate> </ItemsControl.ItemTemplate> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <StackPanel Orientation="Horizontal" /> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> </ListView>
      
      







3. рдПрдХ рдкреАрдбреАрдПрдл рдкреБрд╕реНрддрдХ рдмрдирд╛рдПрдБ



рд╕реЛрдиреА рдХреА рдЗрд▓реЗрдХреНрдЯреНрд░рд┐рдХ рдкреБрд╕реНрддрдХреЛрдВ рдореЗрдВ рдЗрд╕рдХреА рд▓реЛрдХрдкреНрд░рд┐рдпрддрд╛ рдФрд░ рдЕрдЪреНрдЫреЗ рд╕рдорд░реНрдерди рдХреЗ рдХрд╛рд░рдг рдкреАрдбреАрдПрдл рдХреЛ рдЪреБрдирд╛ рдЧрдпрд╛ рдерд╛ред .NET рдореЗрдВ рдкреАрдбреАрдПрдл рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдУрдкрди рд╕реЛрд░реНрд╕ рд▓рд╛рдЗрдмреНрд░реЗрд░реА iTextSharp рд╣реИ (рдЖрдкрдХреЛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕реЗ рдЕрд▓рдЧ рд╕реЗ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рдирд╛ рд╣реЛрдЧрд╛)ред рдпрд╣рд╛рдБ рд╕рдм рдХреБрдЫ рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИред рдЕрдкрд╡рд╛рдж рд╕реЗ рдирд┐рдкрдЯрдиреЗ, рдЫрд╡рд┐ рдХрд╛ рдЖрдХрд╛рд░ рдФрд░ рдлрд╝реЙрдиреНрдЯ рд╕рдорд╛рдпреЛрдЬрд┐рдд рдХрд░рдирд╛, рд╣рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдорд┐рд▓рддреЗ рд╣реИрдВ:

 var document = new Document(PageSize.LETTER); var wri = PdfWriter.GetInstance(document, new FileStream(fileName, FileMode.Create)); document.Open(); foreach (var comic in comics.OrderBy(c => c.Index).ToList()) { var image = Image.GetInstance(new MemoryStream(comic.ImageBytes)); var title = new Paragraph(comic.Index + ". " + comic.Title, titleFont); title.SetAlignment("Center"); document.Add(title); document.Add(image); document.Add(new Phrase(comic.Description, altFont)); document.Add(Chunk.NEXTPAGE); } document.Close();
      
      







рдкрд░рд┐рдгрд╛рдо



рдкрд░рд┐рдгрд╛рдо рдПрдХ рдЖрд╡реЗрджрди рд╣реИ рдЬреЛ рдкреАрдбреАрдПрдл рдХреЛ рдирд┐рд░реНрдпрд╛рдд рдХрд░рдиреЗ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЖрдкрдХреЛ рдЖрд╕рд╛рдиреА рд╕реЗ рдХреЙрдорд┐рдХреНрд╕ рджреЗрдЦрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ:



рд╡реЗрдмрдХреЙрдорд┐рдХ рдЧреНрд░реИрдмрд░ рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ



рдкреБрд╕реНрддрдХ рдкрд░ рдкрд░рд┐рдгрд╛рдо рдХреИрд╕рд╛ рджрд┐рдЦрддрд╛ рд╣реИ рдпрд╣ рд▓реЗрдЦ рдХреА рдкрд╣рд▓реА рддрд╕реНрд╡реАрд░ рдореЗрдВ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред



рд▓реЗрдЦ рд╕реЗ рдХреНрдпрд╛ рдмрдЪрд╛ рд╣реИ



рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд▓реЙрдиреНрдЪ (рдЖрдЗрд╕реЛрд▓реЗрдЯреЗрдбрд╕реНрдЯреЛрд░реЗрдЬ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ) рдХреЗ рдмреАрдЪ рдбрд╛рдЙрдирд▓реЛрдб рдХрд┐рдП рдЧрдП рдбреЗрдЯрд╛ рдХреЛ рдХреИрд╢рд┐рдВрдЧред

рдЕрдиреНрдп рд╡реЗрдмрдХреЙрдорд┐рдХреНрд╕ рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдерди (рдЗрд╕ рдЙрджреНрджреЗрд╢реНрдп рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ IGrabber рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рдкреВрд░реНрд╡-рдЖрдмрдВрдЯрд┐рдд рдХрд┐рдпрд╛, рдФрд░ рдЯрд╛рд╕реНрдХрдкрд░реНрд▓рдЧреНрд░реЗрдЧрдмрд░ рдореЗрдВ рдХреБрдЫ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдкреНрд░рджрд╛рди рдХреАред рдПрдХ рд▓реЗрдЦ рд▓рд┐рдЦрддреЗ рд╕рдордп, рдореИрдВрдиреЗ рд╡реНрд╣рд╛рдЯреНрд╕рдПрдк рдХреЗ рд▓рд┐рдП рд╣рдбрд╝рддрд╛рд▓реА рдЬреЛрдбрд╝реЗ рдФрд░ рд╕рд╛рдЗрдирд╛рдЗрдб рдФрд░ рдЦреБрд╢реА)ред



рд╕рдВрджрд░реНрдн



рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛрдб (C #): Google рдХреЛрдб

.NET рдкрд░ рдкреАрдбреАрдПрдл рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдВ: iTextSharp

рдХреЙрдорд┐рдХреНрд╕: xkcd



рдпреБрдкреАрдбреА:

рдкрд░рд┐рдгрд╛рдореА рдкреАрдбреАрдПрдл рдФрд░ рд╕рдВрдХрд▓рд┐рдд рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЛ рдЕрдкрд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП XHunter рдХрд╛ рдзрдиреНрдпрд╡рд╛рдж!



UPD2:

рдореИрдВ рдпрд╣рд╛рдБ рдПрдХ рдЕрдЪреНрдЫреЗ "рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛" рд▓реЗрдЦ рдХрд╛ рд▓рд┐рдВрдХ рдЫреЛрдбрд╝ рджреВрдВрдЧрд╛ рдЬрд┐рд╕рдореЗрдВ WCF рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХреЙрдорд┐рдХреНрд╕ рдХреЛ рдкрдВрдк рдХрд░рдиреЗ рдХреЗ рд╡рд┐рд╖рдп рдХрд╛ рд╡рд┐рд╡рд░рдг рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ: http://darren-brown.com/?p=37



All Articles