Ramtin

مدیر کل
  • تعداد ارسال ها

    240
  • تاریخ عضویت

  • آخرین بازدید

  • روز های برد

    166

تمامی ارسال های Ramtin

  1. سلام به وین نویسی های عزیز، امروز آموزش استفاده از دیتابیس SQlite در زامارین فرمز رو برای شما آماده کردم. این آموزش بر پایه دیتابیس آماده، درون پروژه می باشد. برای این آموزش نیاز هست که کتابخانه Sqlite-net-pcl رو در هر سه پروژه iOS,Android و UWP نصب کنید. نکته: همیشه ویژوال استودیو را با Run as Administrator باز کنید تا مشکلی برای شما در حین ساخت پروژه، بروز رسانی کتابخانه ها و... پیش نیاید. پروژه ای جدید از نوع Cross Platform App به نام WN XF Database ایجاد نمایید. (نکته: من اینجا اشتباها اومدم توی پوشه ی پروژه های ویژوال استودیو این پروژه رو ایجاد کردم. در اولین نگاه شاید بگید که این که اشکالی نداره، اما وقتی کار کنید میبیند که در پروژه اندروید هر کلاسی که اضافه میشه، عملا رنگ نوشته هاش سفید هست و کار نمیکنه که این به دلیل زیاد شدن آدرس پروژه هست، برای همین بهتر هست همیشه توی پوشه روت درایو هاتون پروژه ها رو بسازید یا حداقل درون یک پوشه درون پوشه روت درایو هاتون ایجاد کنید. من بعد از ساخت پروژه اون رو کات کردم توی درایو G پوشه Sources در کامپیوترم که این مشکل پیش نیاد.) در پنجره بعدی همانند تصویر عمل کنید، یعنی Template از نوع Blank App و UI technology از نوع Xamarin.Forms و Code Sharing strategy از نوع Shared باشه. سپس روی OK کلیک کنید، بعد از این از شما می خواد برای پروژه UWP نسخه SDK تعریف کنید که من 14393 که نسخه سالگرد هست رو انتخاب کردم. پس از ساخت پروژه، پنجره هایی که مربوط به IOS باز شدن رو ببندید. نکته: اگه با ناگت مشکل دارید، یعنی نمی توانید کتابخانه دانلود کنید، نرم افزار Fiddler4 رو دانلود و نصب کنید. پس از نصب آنرا باز کنید و روی WinConfig کلیک کنید، چنانچه از شما پیاپی سوال پرسیده شد، روی YES کلیک کنید تا پنجره ی دیگری برایتان باز شود. در پنجره باز شده روی Exempt all کلیک کنید و روی Save changes کلیک کنید و این پنجره را ببنید. از این پس هر زمانی که میخواهید از ناگت پکیج منیجر استفاده کنید، فقط برنامه Fiddler4 رو باز کنید. روی راه حل (Solution) راست کلیک کنید و روی Manage Nuget Packages for solution را انتخاب کنید. به تب Updates برید و در ابتدا Xamarin.Forms را بروز رسانی کنید، گزینه Xamarin.Forms را تیک بزنید و روی Update کلیک کنید. چنانچه بعد از نصب این قسمت زرد رنگ را دیدید روی Restart کلیک کنید تا ویژوال استودیو ریستارت شود. بعد از ریستارت بصورت خودکار پروژه شما بارگذاری خواهد شد. پس از باز شدن، دوباره به Nuget package manager را باز کنید و در تب Updates همه ی گزینه ها را تیک بزنید و روی Update کلیک کنید تا باقی کتابخانه ها هم بروز رسانی شوند. حال با تب Browse بروید و در قسمت Search این متن را تایپ کنید و اینتر بزنید: sqlite-net-pcl نکته: نسخه های متفاوتی از Sqlite در ناگت وجود دارد اما ما فقط و فقط این نسخه را می خواهیم: این کتابخانه را نصب کنید. نکته: این نسخه توسط Frank a Krueger ساخته شده و تنها نسخه ای هست که اندروید 7 به بالا بدون باگ اجرا میشود. نکته: حتما چک کنید و ببینید که این کتابخانه ها (SQLitePCLRaw) هم خودکار با این پکیج نصب شده باشند، اگر نصب نبودند حتما آنها را خودتان نصب کنیدالبته این عکس مربوط به References پروژه اندروید است. در UWP اینطوری نیست.) حال وقت آن است که دیتابیس را به پروژه اضافه کنیم، من از دیتابیسی که قبلا درون آموزش ساخت کتاب برای ویندوزفون 8.1 ساخته بودم اینجا استفاده کردم. کپی کردن دیتابیس در پروژه UWP. دیتابیس را درون روت پروژه UWP کپی کنید سپس روی آن راست کلیک کرده و روی Properties کلیک کنید. Build Action را روی Content قرار دهید و گزینه Copy to output directory را Copy Always قرار دهید کپی کردن دیتابیس درون پروژه IOS برای اضافه کردن فایل، باید آنها را در پوشه Resources پروژه IOS اضافه کنید. روی دیتابیس راست کلیک کنید و روی Properties کلیک کنید. حتما بررسی کنید که Build Action روی BundleResource و Copy to output روی Copy Always باشد: کپی کردن دیتابیس در پروژه Android در اندروید اضافه کردن فایل به پروژه بسیار جالب است. برای اضافه کردن فایل، ابتدا پوشه ای به نام Raw درون پوشه Resources ایجاد کنید و دیتابیس را درون آن اضافه کنید. روی دیتابیس راست کلیک کرده و Properties را انتخاب کنید و گزینه Build Action را روی AndroidResource و گزینه Copy to output را روی Copy Always قرار دهید. حالا چرا جالبه؟ الان بعد از اضافه کردن فایل به پوشه Raw که ایجاد کردیم، درون پروژه اندروید یک کلاس ایجاد به همین نام ایجاد شد و یک آیدی(شناسه) از نوع Integer برای این فایل ایجاد شد. مثلا برای دسترسی به این فایل درون پروژه اندروید بدین صورت عمل می کنیم: Resources.Raw.myBookDatabase حال شاید برایتان سوال پیش آید که چگونه قرار است این فایل ها را بخوانیم؟! ما باید در پروژه Shared یک اینترفیس interface ایجاد کنید و در هر پروژه به صورت جداگانه دیتابیس را بخوانیم. اینکار را ساخت Dependency می گویند. خب درون پروژه Shared ( پروژه اول درون Solution)، یک کلاس به نام IDatabaseService ایجاد نمایید: فضای نامی SQlite را به قسمت مربوطه اضافه کنید: using SQLite; خب حالا در تعریف کلاس، به جای کلمه class کلمه public interface را بنویسید. الان کدهای زیر را بنویسید: public interface IDatabaseService { SQLiteConnection GetConnection(string fileName); void CopyDatabaseToLocal(string fileName); } خب برای اونهایی که تا حالا با اینترفیس ها کار نکردن، ما اینجا یک تابع بازگشتی به نام GetConnection تعریف کردیم که SQLiteConnection رو باز گردانی خواهد کرد. تابع بعدی، تابع کپی کردن دیتابیس خواهد بود. ما در هر سه پروژه پلتفرم سه کلاس ایجاد خواهیم کرد که از این اینترفیس مشتق میشود. یک کلاس دیگر درون پروژه Shared به نام Extensions ایجاد کنید. این کلاس به صورت static خواهد بود و در واقع یک نوع Extension نویسی برای Exception ها است که قرار است ایجاد کنیم: static class Extensions { public static string Exception(this Exception ex, string starts) { var content = $"{starts} ex: {ex.Message}\r\nSource: {ex.Source}" + $"\r\nTrace: {ex.StackTrace}"; Output(content); return content; } public static void Output(object obj) { System.Diagnostics.Debug.WriteLine(Convert.ToString(obj)); } } تابع اول یک Extension است، تابع را در یک Exception که در try...catch قرار دارد فرا بخوانیم، اگر کد ما استثنا داد، خطا را در پنجره Output ویژوال نمایش خواهد داد(فقط در حالتی که پروژه روی Debug باشد.) خب در پروژه UWP یک کلاس به نام DatabaseService_UWP ایجاد کنید. فضاهای نامی زیر را به قسمت مربوطه اضافه کنید: using System; using SQLite; using Windows.Storage; using System.IO; using Xamarin.Forms; using Windows.ApplicationModel; حالا کلاس اینترفیس را مشتق کلاسی که ایجاد کردید قرار دهید، چنانچه موس را روی IDatabaseService ببرید و روی آن کلیک کنید یک مثلث زیر آن خواهد آمد که خودکار برای شما توابعی که در اینترفیس ایجاد کردیم را برای شما در این کلاس می سازد: تکه کد زیر را پاک کنید: throw new NotImplementedException(); حال کدهای زیر را درون تابع CopyDatabaseToLocal بنویسید: public async void CopyDatabaseToLocal(string fileName) { try { StorageFile storageFile = await ApplicationData.Current.LocalFolder.GetFileAsync(fileName); // injori faghat yebar file ro copy mikonim tuye local folder storageFile = null; return; } catch { } StorageFile databaseFile = await Package.Current.InstalledLocation.GetFileAsync(fileName); await databaseFile.CopyAsync(ApplicationData.Current.LocalFolder); } دیتابیس درون پروژه را به LocalFolder کپی می کنیم. نکته: درون try...catch خط آخر return نوشتیم، اینطوری زمانی که هر بار برنامه باز می شود، اگر فایل دیتابیس درون LocalFolder موجود بود، آنرا کپی نخواهد کرد. این کار برای زمانی است که کاربر بخواهد دیتابیس را بروز رسانی کند و یا آیتمی به آن اضافه کند، اینطوری دیتابیس هر بار ریست نخواهد شد. حال تابع بازگشتی GetConnection را بنویسید: public SQLiteConnection GetConnection(string fileName) { try { var path = Path.Combine(ApplicationData.Current.LocalFolder.Path, fileName); var connection = new SQLiteConnection(path); return connection; } catch (Exception ex) { ex.Exception("DatabaseService_UWP"); } return null; } این تابع کانکشنی به دیتابیس باز می کند که ما بعد از متصل شدن، می توانیم آیتم ها را دریافت کنیم یا اینکه آنها را ویرایش و یا حذف کنیم. خب الان باید تعیین کنیم که این کلاس یک Dependency می باشد. برای اینکار، بالای فضای نامی کد زیر را بنویسید: [assembly: Dependency(typeof(WN_XF_Database.UWP.DatabaseService_UWP))] یعنی اینطوری: [assembly: Dependency(typeof(WN_XF_Database.UWP.DatabaseService_UWP))] namespace WN_XF_Database.UWP { public class DatabaseService_UWP : IDatabaseService حال درون پروژه IOS نیز یک کلاس به نام DatabaseService_IOS ایجاد نمایید. فضاهای نامی زیر را به قسمت مربوطه ی آن اضافه کنید: using SQLite; using System; using System.IO; using Xamarin.Forms; و کلاس آن: [assembly: Dependency(typeof(WN_XF_Database.iOS.DatabaseService_IOS))] namespace WN_XF_Database.iOS { public class DatabaseService_IOS :IDatabaseService { public SQLiteConnection GetConnection(string fileName) { try { var documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); var libraryPath = Path.Combine(documentsPath, "..", "Library"); var path = Path.Combine(libraryPath, fileName); var connection = new SQLiteConnection(path); return connection; } catch (Exception ex) { ex.Exception("DatabaseService_IOS"); } return null; } public void CopyDatabaseToLocal(string fileName) { try { var documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); var libraryPath = Path.Combine(documentsPath, "..", "Library"); var path = Path.Combine(libraryPath, fileName); if (!File.Exists(path)) { // daryafte db az masire nasb shodeye barname using (var sourceStream = File.Open("./" + fileName, FileMode.Open, FileAccess.Read)) { FileStream writeStream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write); ReadWriteStream(sourceStream, writeStream); } } } catch (Exception ex) { ex.Exception("DatabaseService_IOS.CopyDatabaseToLocal"); } } private void ReadWriteStream(Stream readStream, Stream writeStream) { try { int Length = 256; Byte[] buffer = new Byte[Length]; int bytesRead = readStream.Read(buffer, 0, Length); while (bytesRead > 0) { writeStream.Write(buffer, 0, bytesRead); bytesRead = readStream.Read(buffer, 0, Length); } readStream.Close(); writeStream.Close(); } catch (Exception ex) { ex.Exception("DatabaseService_IOS.ReadWriteStream"); } } } } خب کپی کردن دیتابیس از پوشه ی نصبی برنامه پوشه MyDocuments کمی در IOS و اندروید نسبت به UWP فرق داره، همانطور که در بالا می بینید یک تابع private هم برای کپی کردن آن نوشتیم. در پروژه اندروید هم کلاسی به نام DatabaseService_Android ایجاد نمایید. فضاهای نامی مورد نیاز: using SQLite; using System; using System.IO; using System.Threading.Tasks; using Xamarin.Forms; کلاس مورد نظر: [assembly: Dependency(typeof(WN_XF_Database.Droid.DatabaseService_Android))] namespace WN_XF_Database.Droid { public class DatabaseService_Android : IDatabaseService { public SQLiteConnection GetConnection(string fileName) { try { var documentspath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); var path = Path.Combine(documentspath, fileName); var connection = new SQLiteConnection(path); return connection; } catch (Exception ex) { ex.Exception("DatabaseService_Android"); } return null; } public async void CopyDatabaseToLocal(string fileName) { try { var documentspath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); var path = Path.Combine(documentspath, fileName); if (!File.Exists(path)) { var s = Android.App.Application.Context.Resources.OpenRawResource(Resource.Raw.myBookDatabase); FileStream writeStream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write); ReadWriteStream(s, writeStream); } await Task.Delay(1); } catch (Exception ex) { ex.Exception("DatabaseService_Android.CopyDatabaseToLocal"); } } private void ReadWriteStream(Stream readStream, Stream writeStream) { try { int Length = 256; Byte[] buffer = new Byte[Length]; int bytesRead = readStream.Read(buffer, 0, Length); while (bytesRead > 0) { writeStream.Write(buffer, 0, bytesRead); bytesRead = readStream.Read(buffer, 0, Length); } readStream.Close(); writeStream.Close(); } catch (Exception ex) { ex.Exception("DatabaseService_Android.ReadWriteStream"); } } } } خب حالا کلاس ها را ذخیره کنید و همه ی آنها را ببندید. در پروژه Shared یک کلاس به نام Dastan ایجاد کنید. این کلاس در اصل مدل دیتابیسی که من در SQLite ساختم، می باشد. فضای نامی مورد نیاز: using SQLite; کلاس داستان: public class Dastan { [PrimaryKey, AutoIncrement] public int Id { get; set; } public string Name { get; set; } public string Story { get; set; } public override string ToString() { return Name.ToString(); } } جدول من دارای سه ستون می باشد. Id برای شناسه، Name برای نام داستان و Story برای متن داستان. کلاس App.xaml.cs را باز کنید. رشته زیر را به صورت constant ایجاد کنید. این رشته نام فایل دیتابیس ما می باشد. چرا constant؟ زیرا نمی خواهیم به اشتباه آنرا تغییر دهیم. (این مقدار فقط readonly یعنی "فقط خواندنی" در نظر گرفته میشود.) public const string DBName = "myBookDatabase.db3"; خب تابع CopyDb را در این کلاس بنویسید: private void CopyDb() { try { DependencyService.Get<IDatabaseService>().CopyDatabaseToLocal(DBName); } catch (Exception ex) { ex.Exception("App.CopyDb"); } } خب این کد شاید برای شما کمی عجیب باشد! اما اینجا فلسفه ساخت Interface و Dependency را یاد خواهید گرفت. کار تابع Get در DependencyService اینه که یک مقدار از نوع T میگیره(T می تونه هر کلاسی باشه) و با در پلتفرم های مختلف کدی که ما ایجاد کردیم رو صدا میزنه. برای مثال اگر ما پروژه UWP را Deploy کنیم، زمانی که به این کد میرسه، DependencyService میاد interfaceـی که ما به نام IDatabaseService ساختیم رو صدا میزنه، این اینترفیس بصورت عادی هیچی نیست اما چون ما کلاس هایی در سه پلتفرم ایجاد کردیم که هم از این اینترفیس مشتق شده بودند و هم به عنوان Dependency اون ها تعریف کرده بودیم، میاد برای هر پروژه اون کلاس مورد نظر در پلتفرم مورد نظر رو صدا میزنه. که در اینجا تابع CopyDatabaseToLocal را فرا میخونه و کار Copy کردن دیتابیس از فولدر نصب شده برنامه به پوشه MyDocuments رو انجام میده. به عبارتی Dependency بصورت خودکار هنگام اجرای این کد میاد اون کدی که ما در پروژه پلتفرمی خاص ایجاد کردیم رو پیدا می کنه و اون رو فرا می خونه. خب حالا درون constructorـه App بعد از فرا خوانیِ InitializeComponent کد زیر را قرار دهید: CopyDb(); یعنی: public App () { InitializeComponent(); CopyDb(); حالا خط بعدی یعنی MainPage =... را به صورت زیر بنویسید: MainPage = new NavigationPage(new MainPage()); چرا NavigationPage؟ زیرا می خواهیم صفحه های جداگانه بسازیم و آنها را باز کنیم. این کلاس را ذخیره کرده و آنرا ببندید. کلاس دیگر در پروژه Shared به نام DatabaseHelper ایجاد نمایید. فضاهای مورد نیاز: using SQLite; using System; using System.Collections.Generic; using System.Linq; using Xamarin.Forms; کلاس مورد نظر: public class DatabaseHelper { SQLiteConnection con; public DatabaseHelper() { try { con = DependencyService.Get<IDatabaseService>().GetConnection(App.DBName); } catch (Exception ex) { ex.Exception("DatabaseHelper"); } } /// <summary> /// Gereftane kole database be sorate liste /// </summary> /// <returns>Liste db ro barmigardone</returns> public IEnumerable<Dastan> Items() { return (from t in con.Table<Dastan>() select t).ToList(); } /// <summary> /// Gereftane yek dastan /// </summary> /// <param name="id">id e dastane morede nazar</param> /// <returns>dastan ro barmigardone</returns> public Dastan GetItem(int id) { return con.Table<Dastan>().FirstOrDefault(t => t.Id == id); } /// <summary> /// Hazfe yek dastan /// </summary> /// <param name="id">id e dastan</param> public void DeleteItem(int id) { con.Delete<Dastan>(id); } /// <summary> /// Ezafe kardane dastan /// </summary> /// <param name="dastan">dastan</param> public void AddItem(Dastan dastan) { con.Insert(dastan); } /// <summary> /// Beroz rasanie dastan /// </summary> /// <param name="dastan">dastan</param> public void UpdateItem(Dastan dastan) { con.Update(dastan); } } فکر نکنم کدها گنگ باشن. فقط در constructor اومدیم با استفاده از DependencyService تابع GetConnection رو صدا زدیم تا SQLiteConnection فرا خوانده بشه. حال کلاس را ذخیره کرده و آنرا ببندید. صفحه طراحی MainPage را باز نمایید و کدهای زیر را بنویسید: <?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:WN_XF_Database" x:Class="WN_XF_Database.MainPage" Title="WN Db Sample"> <StackLayout> <Label Text="Name" Margin="2"/> <Entry x:Name="txtName" Placeholder="Enter story name"/> <Label Text="Story" Margin="2"/> <Editor x:Name="txtStory" HeightRequest="300"/> <Button x:Name="btnAdd" Text="Add" Clicked="btnAdd_Clicked"/> <Button x:Name="btnShow" Text="Show items" Clicked="btnShow_Clicked"/> </StackLayout> </ContentPage> صفحه را ذخیره کنید، سپس قسمت کدنویسی این صفحه را باز کنید و کدهای دو تابع رویدادهای آن را بنویسید: private void btnAdd_Clicked(object sender, EventArgs e) { var dastan = new Dastan(); var db = new DatabaseHelper(); dastan.Name = txtName.Text; dastan.Story = txtStory.Text; db.AddItem(dastan); } private void btnShow_Clicked(object sender, EventArgs e) { Navigation.PushModalAsync(new StoriesPage()); } تابع رویداد btnAdd_Clicked برای اضافه کردن داستان جدید به دیتابیس است. تابع btnShow_Clicked هم برای باز کردن صفحه ی داستان ها می باشد. StoriesPage صفحه ی ما برای نمایش عناوین داستان ها می باشد. برای ایجاد صفحه ی جدید، روی پروژه Shared راست کلیک کنید و گزینه Add new item را انتخاب کنید. در پنجره ی باز شده، Content Page را انتخاب کنید و نام آنرا StoriesPage قرار دهید. نکته: دو نوع ContentPage وجود دارد، یکی به اسم ContentPage و دیگری به نام ContentPage C# می باشد. نوع اول را انتخاب کنید(اسم بدون C#): کدهای XAML این صفحه را بیاورید و کدهای زیر را درون آن بنویسید: <?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="WN_XF_Database.StoriesPage" Title="Stories"> <ListView x:Name="StoryListView" SeparatorVisibility="Default"> <ListView.ItemTemplate> <DataTemplate> <ViewCell> <Grid HeightRequest="60"> <Grid.GestureRecognizers> <TapGestureRecognizer x:Name="ItemTap" Tapped="ItemTap_Tapped" NumberOfTapsRequired="1"/> </Grid.GestureRecognizers> <Label Text="{Binding Name}" TextColor="Black" VerticalOptions="CenterAndExpand" HorizontalOptions="End" Margin="5"/> </Grid> </ViewCell> </DataTemplate> </ListView.ItemTemplate> </ListView> </ContentPage> صفحه را ذخیره کرده و صفحه کدنویسی آنرا باز کنید. فضاهای نامی مورد نیاز: using System; using System.Linq; using Xamarin.Forms; using Xamarin.Forms.Xaml; تابع بازنویسی شده OnAppearing را بنویسید. این تابع در اصل همان تابع Loaded در پروژه های یونیورسال میباشد! protected override void OnAppearing() { base.OnAppearing(); var db = new DatabaseHelper(); var list = db.Items(); Extensions.Output("Story count: " + list.Count()); StoryListView.ItemsSource = list; } آیتم های دیتابیس را به ItemsSourceـه ListView بایند می کنیم. تابع Tapped را برای آیتم ها می نویسیم: private void ItemTap_Tapped(object sender, EventArgs e) { try { var grid = sender as Grid; if (grid == null) return; var dastan = grid.BindingContext as Dastan; if (dastan == null) return; Navigation.PushModalAsync(new ShowStoryPage(dastan)); } catch (Exception ex) { ex.Exception("ItemTapped"); } } چون ما این تابع را برای Grid ساختیم پس sender را Cast می کنیم به Grid سپس BindingContext یا همان مدل بایندینگ را از نوع داستان Cast می کنیم. در آخر صفحه ShowStoryPage را باز می کنیم و اطلاعات را درون Constructor آن میفرستیم. صفحه ای جدید از نوع Content Page درون پروژه Shared ایجاد کنید و نام آنرا ShowStoryPage بگذارید. درون قسمت طراحی این صفحه کدهای زیر را بنویسید: <?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="WN_XF_Database.ShowStoryPage" Title="Show story"> <ContentPage.Content> <StackLayout> <Label x:Name="txtName" TextColor="Black" HorizontalOptions="End" Font="15" Margin="5"/> <ScrollView> <Label x:Name="txtStory" TextColor="Black" HorizontalOptions="End" HorizontalTextAlignment="End" Margin="10"/> </ScrollView> </StackLayout> </ContentPage.Content> </ContentPage> صفحه را ذخیره کرده و قسمت کدنویسی آنرا باز کنید. در بالای constructor خط زیر را بنویسید: public Dastan CurrentDastan; یک کپی از تابع constructor بگیرید و یک پارامتر ورودی از نوع Dastan به آن اضافه کنید. یعنی: public ShowStoryPage () { InitializeComponent (); } public ShowStoryPage(Dastan dastan) { InitializeComponent(); CurrentDastan = dastan; } حال تابع بازنویسی شده OnAppearing را بنویسید تا اطلاعاتی که بارگذاری شده، را به تکست ها اضافه کنیم: protected override void OnAppearing() { base.OnAppearing(); if (CurrentDastan != null) { txtName.Text = CurrentDastan.Name; txtStory.Text = CurrentDastan.Story; } } به همین راحتی! دانلود سورس کد نمونه منبع: وین نویس
  2. Apiای کوچیکی که من ساختم با استفاده از Asp.Net Mvc Web Api بود. اینم آموزش ساختش: توی فایل WebApiConfig تابع Register کدهای زیر را اضافه کنید: config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("multipart/form-data")); config.Formatters.FormUrlEncodedFormatter.SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("multipart/form-data")); config.Formatters.XmlFormatter.SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("multipart/form-data")); کلاس مورد نیاز : using System.Collections.Generic; using System.Linq; using System.Web.Http; namespace SoorenaSiteApi.Models.Helpers { public static class HeaderHelper { public static string GetHeader(ApiController controller, string key) { try { IEnumerable<string> headerValues; if (controller.Request.Headers.TryGetValues(key, out headerValues)) return headerValues.FirstOrDefault(); } catch { } return string.Empty; } } } کد کنترلر ویت: using Newtonsoft.Json; using SoorenaSiteApi.Models.Helpers; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Net.Http; using System.Net.Http.Headers; using System.Threading.Tasks; using System.Web.Http; namespace SoorenaSiteApi.Controllers { public class WitController : ApiController { const string defaultAccessToken = "3PLCUPJISQTSUUAV3YLXFY3D3365MUTY"; string accessToken = string.Empty; string audioType = string.Empty; [HttpPost, Route("api/wit")] public async Task<object> Upload() { if (!Request.Content.IsMimeMultipartContent()) return new WitResponseObject { Text = "UnsupportedMediaType" }; //throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); accessToken = HeaderHelper.GetHeader(this, "Authorization"); audioType = HeaderHelper.GetHeader(this, "AudioType"); var provider = new MultipartMemoryStreamProvider(); await Request.Content.ReadAsMultipartAsync(provider); WitResponseList list = new WitResponseList(); foreach (var file in provider.Contents) { var filename = file.Headers.ContentDisposition.FileName.Trim('\"'); var buffer = await file.ReadAsByteArrayAsync(); if (string.IsNullOrEmpty(audioType)) audioType = GetType(filename); var wit = await GetCL(buffer, audioType); list.Add(wit); } if (list.Any()) return list; return new WitResponseObject { Text = "ERR" }; } async Task<WitResponseObject> GetCL(byte[] buffer, string audioType) { using (HttpClient client = new HttpClient()) { //$ curl -XPOST 'https://api.wit.ai/speech?v=20160526' \ // -i -L \ // -H "Authorization: Bearer $TOKEN" \ // -H "Content-Type: audio/wav" \ // --data-binary "@sample.wav" // addresse sende stream be wit Uri targetUri = new Uri("https://api.wit.ai/speech?v=20160526"); Dictionary<string, string> headers = new Dictionary<string, string>(); headers.Add("Transfer-encoding", "chunked"); if (string.IsNullOrEmpty(accessToken)) headers.Add("Authorization", "Bearer " + defaultAccessToken); else headers.Add("Authorization", "Bearer " + accessToken); foreach (var item in headers) client.DefaultRequestHeaders.Add(item.Key, item.Value); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(audioType)); using (ByteArrayContent byteContent = new ByteArrayContent(buffer)) { byteContent.Headers.ContentType = new MediaTypeHeaderValue(audioType); HttpResponseMessage response = await client.PostAsync(targetUri, byteContent); var content = new StreamReader(await response.Content.ReadAsStreamAsync()).ReadToEnd(); var wit = JsonConvert.DeserializeObject<WitResponseObject>(content); return wit; } } } string GetType(string filename) { var extension = filename.Substring(filename.LastIndexOf(".") + 1); if (extension.ToLower() == "mp3") return "audio/mpeg3"; else return "audio/wav"; } } public class WitResponseList : List<WitResponseObject> { } public class WitResponseObject { [JsonProperty("msg_id")] public string MessageId { get; set; } [JsonProperty("_text")] public string Text { get; set; } [JsonProperty("entities")] public object Entities { get; set; } } } موفق باشید. منبع: وین نویس
  3. سلام، توی تاپیک قبلی > آموزش ساخت دستیار صوتی و تشخیص گفتار صوتی رو آموزش داده بودم. اما اگه از این کد استفاده کرده باشید می دونید که در بعضی موارد جواب رو نمیده و به احتمال زیاد ف-ی=ل=ت-ر هست. خب برای رفع این مشکل من یه api کوچیک آماده کردم که شما کافیه که فایلی که رکورد کردید رو به این آدرس پست کنید: http://appsoorena.ir/api/wit نمونه کد برای ارسال: async Task<string> GetAsync(StorageFile file) { try { using (HttpClient httpClient = new HttpClient()) { MultipartFormDataContent form = new MultipartFormDataContent(); using (Stream fileStream = (await file.OpenAsync(FileAccessMode.ReadWrite)).AsStream()) { byte[] bytes = ReadStream(fileStream); form.Add(new ByteArrayContent(bytes, 0, bytes.Length), "file", file.Name); HttpResponseMessage response = await httpClient.PostAsync("http://appsoorena.ir/api/wit", form); response.EnsureSuccessStatusCode(); httpClient.Dispose(); string result = response.Content.ReadAsStringAsync().Result; return result; } } } catch (Exception ex) { Debug.WriteLine("Ex: " + ex.Message + "\r\n\r\n" + ex.Source + "\r\n\r\n" + ex.StackTrace); } return ""; } به صورت پیشفرض این میاد از AccessToken من استفاده میکنه و ارسال فایل به ویت رو انجام میده، اگه مایل هستید که از AccessToken خودتون استفاده کنید، کافیه که توی هدر ارسالی نام هدر رو Authorization بذارید و مقدار اون رو برابر با AccessToken خودتون قرار بدید: مثال: httpClient.DefaultRequestHeaders.Add("Authorization", "ACCESS TOKEN E SHOMA"); نکته: این API قابلیت ارسال همزمان چندین فایل رو داره: async Task<string> GetAsync(IReadOnlyList<StorageFile> files) { try { using (HttpClient httpClient = new HttpClient()) { //httpClient.DefaultRequestHeaders.Add("Authorization", "ACCESS TOKEN E SHOMA"); MultipartFormDataContent form = new MultipartFormDataContent(); Dictionary<string, byte[]> dic = new Dictionary<string, byte[]>(); foreach (StorageFile f in files) { using (Stream fileStream = (await f.OpenAsync(FileAccessMode.ReadWrite)).AsStream()) { byte[] bytes = ReadStream(fileStream); string name = f.Name; dic.Add(name, bytes); } } foreach (var f in dic) form.Add(new ByteArrayContent(f.Value, 0, f.Value.Length), "file", f.Key); HttpResponseMessage response = await httpClient.PostAsync("http://appsoorena.ir/api/wit", form); response.EnsureSuccessStatusCode(); httpClient.Dispose(); string result = response.Content.ReadAsStringAsync().Result; return result; } } catch (Exception ex) { Debug.WriteLine("Ex: " + ex.Message + "\r\n\r\n" + ex.Source + "\r\n\r\n" + ex.StackTrace); } return ""; } جواب به صورت لیستی از کلاس WitResponseObject خواهد بود. در اینجا من 8 فایل ارسال کردم که اینم جوابش: [ { "msg_id": "0XuSI5fNDdIXwvg2w", "_text": "برای", "entities": { "intent": [ { "confidence": 1, "value": "کاری " } ] } }, { "msg_id": "0jur6vqRHwR5iULOx", "_text": "دانلود", "entities": { "intent": [ { "confidence": 1, "value": "کاری " } ] } }, { "msg_id": "0bjs6UfOFV5RWxlA6", "_text": "این", "entities": { "intent": [ { "confidence": 1, "value": "کاری " } ] } }, { "msg_id": "0sPszLjV7Emx81ZFo", "_text": "کد", "entities": { "intent": [ { "confidence": 1, "value": "کاری " } ] } }, { "msg_id": "0VUVcyH4DwD3O2rqH", "_text": "زیر", "entities": { "intent": [ { "confidence": 1, "value": "کاری " } ] } }, { "msg_id": "0EqbLSnVxjoIZa3rs", "_text": "راه", "entities": { "intent": [ { "confidence": 1, "value": "کاری " } ] } }, { "msg_id": "0amyxK8K5g1bCqBep", "_text": "اسکن", "entities": { "intent": [ { "confidence": 1, "value": "کاری " } ] } }, { "msg_id": "0Joftm7K5HpGOyNFB", "_text": "کنید", "entities": { "intent": [ { "confidence": 1, "value": "کاری " } ] } } ] موفق باشید. منبع: وین نویس
  4. آموزش تبدیل گفتار به نوشتار در ویندوز یکپارچه. کتاب الکترونیک آموزش پیوست شد. پروژه نمونه را می توانید از گیتهاب دانلود نمایید: GitHub - ParseDev/WitAiUWP: Wit Ai Sample for Windows Universal Platfo... نکته چنانچه با این روش مشکل در دریافت دارید، پست زیر رو ببینید: منبع: وین نویس WitAi Speech Recognition.pdf
  5. سلام وقت بخیر، از اونجا که برای دوست عزیزمون بهروز برای پخش موزیک یا ویدیو در پس زمینه مشکل ایجاد شده، فکر کردم این آموزش رو بذارم برای دوستانی که مشکلی مشابه دارند. نکته: من ویژوال استودیو روی کامپیوترم ندارم پس شاید بعضی از کدهام اشتباه تایپی داشته باشند، پس خودتون با Intellisense ویژوال استودیو اون رو درست کنید. خب پروژه جدیدی از نوع یکپارچه با ورژن SDK نسخه 10.0.14393 به نام WN_BackgroundPlayback ایجاد نمایید. درون این پروژه یک کلاس اضافه کنید و کدهای زیر رو درون اون بنویسید: using Windows.Media.Playback; // in code az sample e MS copy shode namespace WN_BackgroundPlayback { class PlaybackService { // sakhte intanse az class static PlaybackService instance; public static PlaybackService Instance { get { if (instance == null) instance = new PlaybackService(); return instance; } } // har appi mitone ye MediaPlayer dashte bashe ke dar tamame safhat mitone azash estefade kone public MediaPlayer Player { get; private set; } public PlaybackService() { // yadeton bashe hamishe AutoPlay ro false bezarin ta moshkeli baraton pish nayad Player = new MediaPlayer {AutoPlay = false}; } } } سپس این کلاس رو ذخیره کنید و آنرا ببندید. حال فایل Package.appxmanifest را با CodeViewer باز کنید (اگه اشتباه نکنم روش راست کلیک که کنید دومین گزینه باید این فایل رو بصورت xml براتون باز کنه) خب اینجا درون تگِ Capabalities کد زیر را بنویسید: <uap3:Capability Name="backgroundMediaPlayback" /> که کد کلی باید بدین صورت باشد: <Capabilities> <Capability Name="internetClient" /> <uap3:Capability Name="backgroundMediaPlayback" /> </Capabilities> حال صفحه را ذخیره و آنرا ببندید. درون صفحه MainPage یک کنترل MediaPlayerElement قرار دهید (این کنترل از SDK 14393 به بعد قابل استفاده است!!) و یک دکمه که خاصیت Click را برای آن تعریف کرده باشید اضافه کنید: <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <Button x:Name="btnPlay" Content="Play" Click="btnPlay_Clicked" /> <MediaPlayerElement x:Name="mediaPlayer" Grid.Row="1" AreTransportControlsEnabled="True" AutoPlay="False" /> </Grid> اکنون صفحه کدنویسی سی شارپ MainPage رو باز کنید و فضای نامی زیر رو به قسمت فضاهای نامی اضافه کنید: using Windows.Media.Playback; بالای کُنستراکتور (public MainPage...) این کد رو بنویسید: public MediaPlayer Player => PlaybackService.Instance.Player; حالا درون کُنستراکتور رویداد loadedـه صفحه را ایجاد نمایید: public MainPage() { InitializeComponent(); Loaded += MainPage_Loaded; } تابع آن: private void MainPage_Loaded(object sender, RoutedEventArgs e) { mediaPlayer.SetMediaPlayer(Player); } اکنون درون تابع رویداد کلیک دکمه کدهای زیر را بنویسید: var item = new MediaPlaybackItem(MediaSource.CreateFromUri(new Uri("http://dl.songdl.xyz/sOng/Album/Saman.Jalili-Ch.Haale.Khoobie/Saman.Jalili_06-Raahat.Maro.mp3"))); Player.Source = item; دقیقا یادم نیست برای اینکه از اینا استفاده کنید چه فضاهای نامی ای نیاز هست که اضافه کنید. اگر دیدید که رنگ زیر کلمات قرمز شد موس را چند ثانیه روی آن نگه دارید ویژوال استودیو به شما یک لامپ نشان میدهد که چنانچه روی آن کلیک کنید، یک لیست نشان خواهد داد که کزینه اول را در این لیست انتخاب کنید تا فضای نامی به صفحه اضافه شود. خب تمام شد ! پروژه را اجرا کرده و آنرا امتحان نمایید. نکات اضافی: برای نمایش آهنگ در SMTC نیاز هست که مقدار SMTCـه MediaPlayer را از آن گرفته و آنرا بروز رسانی نمایید.(از اینجا به بعد کپی شده از سورناست!) برای اینکار کافی است که شما در بالای کنستراکتور کد زیر را بنویسید: public SystemMediaTransportControls smtc = null; سپس درون Loaded کد زیر را بعد از کدی که در بالا نوشتید، درون try..catch بنویسید: try { smtc = Player.SystemMediaTransportControls; } catch {} با این کار SMTC پلیر را میگیریم. حال تابع زیر را جهت بروز رسانی کردن SMTC بنویسید public void UpdateSMTC(string singer, string title, string cover) { if (smtc == null) return; smtc.PlaybackStatus = MediaPlaybackStatus.Playing; smtc.DisplayUpdater.Type = MediaPlaybackType.Music; smtc.DisplayUpdater.MusicProperties.AlbumTitle = smtc.DisplayUpdater.MusicProperties.Title = title; smtc.DisplayUpdater.MusicProperties.AlbumArtist = smtc.DisplayUpdater.MusicProperties.Artist = singer; if (!string.IsNullOrEmpty(cover)) smtc.DisplayUpdater.Thumbnail = RandomAccessStreamReference.CreateFromUri(new System.Uri(cover)); smtc.DisplayUpdater.Update(); } حال درون رویداد کلیک بعد از کد پلی کردن، برای بروز رسانی آهنگ کافیست اینگونه عمل نمایید: UpdateSMTC("Saman Jalili", "Rahat Maro", "http://dl.songdl.xyz/sOng/Album/Saman.Jalili-Ch.Haale.Khoobie/Saman.Jalili-Che.Haale.Khoobie.jpg"); به همین سادگی! موفق باشید. منبع هم که همیشه وین نویس هست!
  6. سلام، من همین روش رو برای سورنا به کار بردم و توی موبایل هم کار میکنه و درست هست و حتی ویدیو هم در پس زمینه پخش میشه. ساده ترین راه هم همینه. موفق باشید.
  7. سلام، بصورت پیشفرض Encoding 1252 در باندل نهایی افزوده نمیشه. برای اینکار Propertiesـه پروژه رو باز کنید و به تب Android Options بروید. در این صفحه از تب Linker رو انتخاب کنید و گزینه Linking رو روی Sdk Assemblies Only رو انتخاب کنید. در قسمت Additional supported encodings هم گزینه west رو تیک بزنید. همین! موفق باشید.
  8. c#

    سلام، به این کار File Association میگن. توی برنامه های تحت دسکتاپ باید در رجیستری این کار رو انجام داد که برنامه باید دسترسی ادمین (Run As Admin) داشته باشه. خوشبختانه توی UWP زیاد کاری نمیخواد انجام داد! برای اینکار کافیه یک Declaration از نوع File Type Associations ایجاد کنید و فرمت هایی که می خواهید رو بنویسید. سپس باید در فایل App.xaml.cs تابع OnFileActivated رو بازنویسی کنید و فایل هایی که با برنامه شما باز میشن رو هندل کنید. اگه اشتباه نکنم شما فقط یک آیکون می تونید برای این فایل ها بذارید. کلا کاریه که پلیرها انجام میدن. ساده شده میتونید پروژه AssociationLaunching رو در سمپل های مایکروسافت نگاه کنید. اگه نیاز به آموزش داشتید بگید تا بذارم. موفق باشید.
  9. سلام آموزشش قبلا گذاشته شده: موفق باشید.
  10. سلام، با عرض پوزش بابت دیر پاسخ دادن، توی ویندوز 10(چه موبایل چه دسکتاپ) چیزی به نام ساخت Setup نداریم. کلا توی پلتفرم های موبایل پکیج باندل(bundle package) ایجاد میشه که توی ویندوز 10 هم این کار باید انجام شه. فایل نهایی با فرمت appx و appxbundle خواهد بود. Deploy در اصل برنامه رو میاد روی گوشی یا کامپیوتر نصب و اجرا می کنه. اینم آموزش تصویری ساخت باندل: https://www.win-nevis.com/Projects/Tutorial/Video/WN%20Creating%20Bundle%20in%20UWP.mp4 لینک کمکی: http://uploadboy.com/zi4w2lconrqh/1179/mp4 موفق باشید.
  11. سلام، آموزش تصویری به دو صورت آماده شده: 1. فایل exe که به نظرم بهتر هست همین رو دانلود کنید(هر جا دیدید فیلم Pause شد دکمه Space رو بزنید تا ادامه فیلم رو ببینید): http://uploadboy.com/qts6dhjcgesm/1099/zip 2. فایل MP4: http://uploadboy.com/uqo0hzmjk91d/1099/rar موفق باشید.
  12. سلام، وقت بخیر، تا جایی که من میدونم اسم فونت یکان B Yekan هست نه Yekan! برای استفاده از فونت ها یا هر چیزی که داخل خود پروژه هست، باید مقدار ms-appx:/// را قبل از آدرس اون بنویسیم. مثلا شما نوشتی: head.Append("@font-face {" + "font-family: 'yekan'" + " url('/other/yekan.ttf') format('ttf');" + "}" + "h1, h2, h3, h4, h5, h6, p{font-family:yekan;}" + "p{font-size{15px;}" + "h1{font-size:25px;}"); که اینجا باید yekan ها به B Yekan و /other/yekan.ttf به ms-appx:///other/yekan.ttf تغییر نام پیدا کنن. نکته: من برای فونت یکان پوشه other رو توی روت پروژه ام ساختم. پس کد بالا میشه: head.Append("@font-face {" + "font-family: 'B Yekan'" + " url('ms-appx:////other/yekan.ttf') format('ttf');" + "}" + "h1, h2, h3, h4, h5, h6, p{font-family:B Yekan;}" + "p{font-size{15px;}" + "h1{font-size:25px;}"); فونت یکان پیوست شد. موفق باشید. yekan.zip
  13. سلام، این کاری که الان من اینجا انجام دادم شدنی هست اما نمیدونم که آیا بابت کلیکی که میشه پولی میدن یا خیر! معمولا تمامی تبلیغاتی که نشون داده میشه داخل Tagـه Html ای به نام iFrame هست. شما کافی هست که این تگ رو پیدا کنید و مقدار srcـه اون رو بگیرید و داخل کنترل WebView به اون Navigate بشید. همین! روش انجام کار: مثلا وین نویس از Anetwork استفاده میکنه. روی یکی از تبلیغات راست کلیک کنید و روی Inspect کلیک کنید. بعد از زدن این گزینه صفحه ای مانند زیر برای شما باز خواهد شد: تگ iframe را می توانید در این قسمت ببینید، روی آن راست کلیک کرده، سپس Copy را بزنید و روی Copy Element کلیک کنید. برنامه Notepad را باز کنید و متن کپی شده را در آن Paste کنید. سپس آدرسی که درون src="" نوشته شده را کپی کنید: تگ iframe: <iframe src="https://ad.anetwork.ir/showad/c.php?adwidth=300&adheight=100&aduser=1470500719&awrey=41" height="100" width="300" frameborder="0" scrolling="no" style="background: #FFF url(https://static-cdn.anetwork.ir/img/loader.gif) no-repeat center;"></iframe> آدرس کپی شده: https://ad.anetwork.ir/showad/c.php?adwidth=300&adheight=100&aduser=1470500719&awrey=41 حالا پروژه جدیدی بسازید و داخل صفحه کنترل WebView قرار بدید: <WebView x:Name="webView" Width="300" Height="60" NavigationStarting="webView_NavigationStarting"/> صفحه کدنویسی را باز کنید و بالای Constructorـه صفحه این دو کد رو بنویسید: /// <summary> /// addresse tablighemon /// </summary> const string adsAddress = "https://ad.anetwork.ir/showad/c.php?adwidth=300&adheight=100&aduser=1470500719&awrey=11"; /// <summary> /// addrese track kardane ye tabligh dakhele aNetwork injorie: /// http://ad-track.anetwork.ir/nclick/g/yLNWEb9QfpbTf6GSVHwhpLg55KGn8X1Pk1wZJgCn176taRQyB7uyaVpNnUxxUfctL/aHR0cDovL3B1Ymxpc2hlcmkuaXI= /// </summary> const string trackAddressContains = "ad-track.anetwork.ir"; آدرس اول آدرس تبلیغ اولیه ماست(هر بار که این آدرس باز میشود تبلیغ تغییر می کند. حتی اگر زمانی که کاربر موس را روی تبلیغ برده و روی علامت ضربدر آن کلیک کند، تبلیغ عوض خواهد شد.) آدرس دوم آدرس تِرَک کردن هست، برای مثال روی تبلیغ راست کلیک کنید و Copy link address را بزنید تا آدرسی مانند زیر ببنید: http://ad-track.anetwork.ir/nclick/g/yLNWEb9QfpbTf6GSVHwhpLg55KGn8X1Pk1wZJgCn176taRQyB7uyaVpNnUxxUfctL/aHR0cDovL3B1Ymxpc2hlcmkuaXI= کل آدرس برای ما مهم نیست ما فقط قسمت را می خواهیم که بین http:// هست و اولین /(اسلش) که در اینجا ad-track.anetwork.ir است. تابع زیر برای باز کردن لینک درون مرورگر پیشفرض ویندوز است: public async void OpenUrlInBrowser(Uri uri) { await Windows.System.Launcher.LaunchUriAsync(uri); } حال تابع NavigationStarting را برای کنترل WebView بنویسید: private void webView_NavigationStarting(WebView sender, WebViewNavigationStartingEventArgs args) { // age uri e safhe ei ke mikhaim baz konim, null nabod // va tuye addresse oun addresse tracke ma vojod dasht if (null != args.Uri && args.Uri.AbsoluteUri.Contains(trackAddressContains)) { // navigation ro cancel mikonim, chon nemikhaim oun ro dar webview baz konim args.Cancel = true; // oun address ro ba morogar baz mikonim OpenUrlInBrowser(args.Uri); } } حال نیاز هست که رویداد و تابع Loadedـه صفحه رو بسازیم و داخل اون تابع آدرس تبلیغمون رو با WebView باز کنیم. این تابع رو من درون constructorـه صفحه ایجاد کردم: Loaded += (s, e) => webView.Navigate(new Uri(adsAddress)); + پروژه نمونه پیوست شد. (بعد از باز کردن پروژه، Rebuild Solution بزنید.) موفق باشید. Advertising Sample.zip
  14. سلام، کد XAML: <StackPanel Margin="10,40,0,0"> <TextBlock Text="Simple Camera" FontSize="20"/> <Button Name="myCamButton" Content="Start Camera" Height="40" Width="120" Click="myCamButton_Click"/> <Image Margin="0,20,0,0" Name="capturedImage" Height="300" Width="300"/> </StackPanel> فضاهای نامی مورد نیاز: using Windows.Media.Capture; using Windows.Storage; using Windows.Storage.Streams; using Windows.UI.Xaml.Media.Imaging; کد سی شارپ: async private void myCamButton_Click(object sender, RoutedEventArgs e) { CameraCaptureUI captureUI = new CameraCaptureUI(); captureUI.PhotoSettings.Format = CameraCaptureUIPhotoFormat.Jpeg; StorageFile photo = await captureUI.CaptureFileAsync(CameraCaptureUIMode.Photo); BitmapImage bitmapImage = new BitmapImage(); using (IRandomAccessStream fileStream = await photo.OpenAsync(FileAccessMode.Read)) { bitmapImage.SetSource(fileStream); } capturedImage.Source = bitmapImage; } نکته: برای استفاده از دوربین باید در فایل package.appxmanifest در تب Capabilities گزینه Microphone را تیک بزنید تا با خطای UnauthorizeAccess مواجه نشوید: پروژه نمونه پیوست شد. موفق باشید. Camera Sample.zip
  15. پروژه نمونه پیوست شد. موفق باشید.
  16. سلام کافیه در فایل package.appxmanifest در تب Capabilities گزینه Microphone را تیک بزنید تا این مشکل برطرف گردد موفق باشید. پست زیر آپدیت شد. نمونه کد افزوده شد. https://www.win-nevis.com/topic/400-%DB%8C%DA%A9-%D8%AF%D9%88%D8%B1%D8%A8%DB%8C%D9%86-%D8%B3%D8%A7%D8%AF%D9%87-%D8%AF%D8%B1-uwp/ موفق باشید.
  17. سلام، آدرس زیر تمام API زرین پال رو آموزش داده: https://zarinpal-lab.github.io/API-Docs شما ابتدا باید یک کلاس مثل زیر باید داشته باشید: public class LoginBody { public string grant_type { get; set; } public string client_id { get; set; } public string client_secret { get; set; } public string username { get; set; } public string password { get; set; } public string scope { get; set; } public bool is_web_app { get; set; } } که به صورت زیر باید سریالایزش کنید به JSON:(اینجا با Json.Net کلاس رو سریالایز کردیم) LoginBody o = new LoginBody(); o.client_id = Constant.ClientId; o.client_secret = Constant.ClientSecret; o.grant_type = "password"; o.is_web_app = false; o.username = email; o.password = password; o.scope = "full-access"; var v = JsonConvert.SerializeObject(o); متاسفانه اینجا نیازی به ClientId و ClientSecret دارید که تا جایی که من میدونم فقط این ها رو در اختیار برنامه نویسای خودشون قرار میدن. در کل روش کار اینطوریه که اول نیاز به AccessToken دارید که با کد بالا و ارسال اون به آدرس زیر (پست کردن اطلاعات با متد application/json)، دسترسی میگیرید: https://api.zarinpal.com/rest/v3/oauth/accessToken.json سپس باید کیف پول ها رو دریافت کنید و آیدی کیف پول رو درخواست بفرستید به آدرس زیر تا تراکنش ها رو براتون نشون بده: https://api.zarinpal.com/rest/v3/transaction/withdraw.json مثلا این اطلاعات رو: { "card_id": "12ygjev1273wdwqdqw", "amount": 5000, "purse": 1 } موفق باشید.
  18. فروش کتاب برنامه نویسی ویندوزفون 8.1. تعداد صفحات: 440 حجم کتاب: 11 مگابایت نوع کتاب: PDF نویسنده: نصراله جوکار سایت سازنده: وین نویس قیمت کتاب: رایگان نکته: چنانچه موقع انتخاب درگاه خود به مشکل برخوردید، لطفا درگاه بانک ملت را انتخاب نمایید. نکته: پرداخت به صورت آنی انجام می شود. فهرست آموزش ها: پیش نیاز ها فعال سازیHyper-V ویندوز ۸/۸٫۱ نصب ویژوال استودیو آموزش ساخت اکانت مایکروسافت استور(این روش از کار افتاده) باز کردن ویژوال استودیو و آشنایی با آن آموزش ویژوال استودیو ساخت اولین پروژه آموزش آنلاک کردن گوشی راه حل های ویژوال استودیو داده ها و اطلاعات الگوریتم زبان برنامه نویسی متغیرها کار با متغیرها رشته ها Integer ها جمع کردن تفریق کردن ضرب کردن تقسیم کردن اعداد اعشاری اعداد اعشاری با دقت معمولی قالب بندی رشته ها MessageDialog(نمایش دهنده پیغام) آشنایی با Taskها تاریخ ها قالب بندی تاریخ ها کار با تاریخ متد یا تابع ایجاد یک تابع محدوده ها کنترل روند اجرای برنامه تصمیم گیری در برنامه دستور if دستور else بررسی چندین شرط دستورات ifهای تو در تو عملگرهای مقایسه ای عملگر مخالف عملگر کوچکتر عملگر کوچکتر یا مساوی عملگر بزرگتر و بزرگتر مساوی عملگرهای And و Or منطقی استفاده از عملگر And منطقی مقایسه رشته ها انتخاب میان حالتها با استفاده از switch انتخاب های چندگانه در دستور switch دستور default حلقه ها حلقه for شمارش معکوس در حلقه حلقه foreach حلقه do حلقه while حلقه های تو در تو خروج زودهنگام از حلقه دستور continue حلقه های بی نهایت آرایه ها استفاده از foreach انتقال آرایه به عنوان پارامتر مرتب سازی آرایه ها حرکت به عقب در آرایه ها مقدار دهی اولیه به آرایه ها شمارنده ها ثابت ها کلاس ها کار با لیست ها بازنویسی تابع ToString جستجو در لیست معرفی XAML درک فضاهای نامی XAML درک ارتباط میان .xaml و .xaml.cs مرور کنترل های رایج XAML پوسته و استایل های XAML کار با منو دستورات (Command Bar) آموزش ساخت و استفاده از UserControl کار با انیمیشن ها ساخت صفحه جدید در پروژه(Navigate Pages) آموزش Parse کردن خبرخوان یک سایت وردپرسی(RSS Reader) آموزش Background Notification (ارسال نوتیفیکیشن در پس زمینه) آموزش های متفرقه: آموزش دانلود در پس زمینه آموزش دیتابیس SQLite آموزش ساخت پخش کننده یا همان Media Player آموزش ارسال نرم افزار به استور نکته ای جالب درباره آموزش ساخت Media Player: در این آموزش کار با Gesture را می آموزیم. با استفاده از لمس انگشت از پایین به بالا و از بالا به پایین در سمت چپ صفحه میزان صدا را تنظیم میکنیم. در سمت راست نیز همین کار را برای تنظیم روشنایی انجام میدهیم. با استفاده از کشیدن انگشت از سمت راست به سمت چپ و از سمت چپ به سمت راست فیلم یا آهنگ موردنظر را جلو یا عقب میکنیم. نکته: بعضی از پروژه ها و مطالب آموزشی این کتاب به صورت Universal (یعنی هم برای ویندوز و هم برای ویندوزفون) برای یادگیری این نوع پروژه ها، کار شده است. برای خرید به لینک زیر بروید: http://s1.picofile.com/file/8261043392/prgfawp.pdf.html منبع: وین نویس
  19. چارچوب XAML راه های بسیاری را به ما می دهند تا بتوانیم ظاهر برنامه هایمان را سفارشی سازی کنیم. استایل دادن به کنترل ها Style ها به شما اجازه می دهند که خواص کنترل ها را تنظیم کرده و از آن تنظیمات برای ظاهر چندین کنترل استفاده نماییم قالب های کنترل می توانید ساختار بصری و رفتار بصیری یک کنترل را با ساخت قالب برای کنترل هایتان در چارچوب XAML سفارشی سازی کنید. ResourceDictionary و منابع XAML توضیح می دهد که چگونه یک عنصر ResourceDictionary و منابع کلیدی تعریف می شود، و چگونه منابع XAML به باقی منابعی که شما تعریف کردید بخشی از برنامه یا پکیج برنامه شما باشد. منابع پوسته در XAML منابع پوسته ها در XAML مجموعه ای از تنظیمات منابعی است که مقادیر مختلفی را بسته به پوسته ای که در سیستم عامل فعال است، تعیین می کند. سه پوسته در چارچوب XAML پشتیبانی می شوند "تاریک" ، "روشن" ، "کنتراست بالا" | Dark, Light, HighContrast استایل کنترل ها شما می توانید ظاهر نرم افزار های خود را به روش های گوناگونی سفارشی سازی کنید. Style ها به شما اجازه می دهند که خواص کنترل ها را تنظیم کرده و از آن تنظیمات برای ظاهر چندین کنترل استفاده نماییم. شما یک قالب کنترل(Control Template) را زمانی ایجاد می کنید که می خواهید ساختار بصری و رفتار بصری کنترل را سفارشی سازی کنید. اصول پایه استایل دهی از استایل ها برای استخراج تنظیمات خواص بصری که می توانند دوباره استفاده مجدد شوند، استفاده می کنیم. در اینجا نمونه ای می زنیم که نشان می دهد سه دکمه با یک استایل که خواص BorderBrush، BorderThickness و Foreground برای آن تعیین شده است، استفاده می کنند. با اعمال یک استایل، شما می توانید کنترل هایی شبیه به هم ایجاد کنید بدون آنگه دوباره آن تنظیمات را برای هر کنترل به طور جداگانه تعیین کنید. شما می توانید یک استایل را به صورد درونی برای یک کنترل یا یک منبع قابل استفاده تعیین کنید. منابع می تواند در صفحه های XAML مورد نظرمان، درون صفحه App.xaml یا در صفحهات جداگانه که فایل XAMLـه ResourceDictionary نامیده می شوند تعریف کنید. یک فایل منبع دیکشنری XAML می تواند در سراسر برنامه به اشتراک گذاشته شود، بیش از یک منبع دیکشنری می تواند در یک برنامه ادغام شود. هر جایی که منبع تعریف شده است تعیین می کند که حوزه استفاده از آن چه محدوده ای داشته باشد. منابع سطع صحفه(درون یک صفحه XAML) فقط در همان صفحه ای که تعریف شده اند قابل استفاده است. اگر منابع با کلیدی که در App.xaml باشد درون صفحه همنام باشد، منبعی که درون صفحه، منبع درون App.xaml را بازنویسی می کند. اگر یک منبع در فایل های دیکشنری جداگانه ای تعریف شود، حوزه استفاده آن توسط جایی که این منبع به آن اشاره می کند، تعیین می شود. در تعریف استایل، شما نیاز به یک ویژگی به نام TargetType(نوع هدف)، و یک کالکشن از یک یا چندین عنصر Setter. ویژگی TargetType یک رشته است که FrameworkElementـی را برای اعمال در استایل مشخص می کند. مقدار TargetType باید از نوع یک FrameworkElement مشتق شده باشد که توسط Windows Runtime یا یک نوع سفارشی که درون برنامه تعریف شده و در دسترس است، باشد. اگر شما سعی کنید که یک استایل را برای یک کنترل اعمال کنید و نوع کنترل مورد نظر با ویژگی TargetType مطابقت نداشته باشد، یک استثنا(Exception) دریافت خواهید کرد. هر عنصر Setter دارای یک Property(خاصیت) و یک Value(مقدار) است. تنظیمات این خواص نشان می دهد که تنظیمات خواص کنترل و مقادیر آن خواص برای چه چیزی اعمال شده است. شما می تواند Setter.Value را با هر عنصر یا خاصیت عنصری تنظیم کنید. کد XAMLـی که اینجاست، استایل هایی که به دکمه ها در عکس پیشین اعمال شده بود را نشان می دهد. در این XAML، در ابتدا دو عنصر Setter در بدنه به عنوان ویژگی استفاده شده است، اما آخرین Setter، برای تعیین خاصیت BorderBrush در بدنه به عنوان عنصر استفاده شده است. در این نمونه از ویژگی x:Key که کلید استایل را تعیین می کند استفاده نشده است، پس استایل به صور ضمنی برای دکمه ها اعمال می شود. اعمال استایل های ضمنی درون بخش بعدی توضیح خواهد شد. <Page.Resources> <Style TargetType="Button"> <Setter Property="BorderThickness" Value="5" /> <Setter Property="Foreground" Value="Blue" /> <Setter Property="BorderBrush"> <Setter.Value> <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1"> <GradientStop Color="Yellow" Offset="0.0" /> <GradientStop Color="Red" Offset="0.25" /> <GradientStop Color="Blue" Offset="0.75" /> <GradientStop Color="LimeGreen" Offset="1.0" /> </LinearGradientBrush> </Setter.Value> </Setter> </Style> </Page.Resources> <StackPanel Orientation="Horizontal"> <Button Content="Button" /> <Button Content="Button" /> <Button Content="Button" /> </StackPanel> اعمال یک استایل ضمنی یا صریح اگر شما درون یک منبع استایلی را تعریف کنید، دو نوم راه برای اعمال آن برای کنترل خود دارید: · به صورت ضمنی، با تعیین فقط یک TargetType برای استایل. (یعنی کلیدی تعریف نکنید) · به صورت صریح، با مشخص کردن یک TargetType و یک ویژگی کلید x:Key برای استایل و سپس با تنظیم این استایل با استفاده از کد {StaticResource} و نام کلید جلوی آن. اگر استایلی دارای ویژگی x:Key باشد، شما می توانید فقط برای کنترل هایی که می خواهید این استایل را داشته باشند با تعیین کلید این استایل آنرا تنظیم و اعمال کنید. تضاد این موضوع، آن است که استایل را بدون ویژگی x:Key تعریف کیند تا به طور خودکار برای همه ی کنترل هایی که درون TargetTypeـه استایل تعیین شود که به صورت صریح تنظیمات استایل تعریف نشده است، اعمال شود. این دو دکمه نمونه ای از استایل ضمنی و صریح را نشان می دهند: در این مثال، اولین استایل دارای یک ویژگی x:Key است و TargetType آن برابر با Button است. اولین خاصیت استایل دکمه، به این کلید تنظیم شده است، پس این استایل از نوع صریح را اعمال کرده است. دومین استایل به صورت ضمنی برای دکمه دوم اعمال شده است چرا که TargetTypeـه آن برابر با Button است و استایل آن نیز بدون ویژگی x:Key است. <Page.Resources> <Style x:Key="PurpleStyle" TargetType="Button"> <Setter Property="FontFamily" Value="Lucida Sans Unicode" /> <Setter Property="FontStyle" Value="Italic" /> <Setter Property="FontSize" Value="14" /> <Setter Property="Foreground" Value="MediumOrchid" /> </Style> <Style TargetType="Button"> <Setter Property="FontFamily" Value="Lucida Sans Unicode" /> <Setter Property="FontStyle" Value="Italic" /> <Setter Property="FontSize" Value="14" /> <Setter Property="RenderTransform"> <Setter.Value> <RotateTransform Angle="25" /> </Setter.Value> </Setter> <Setter Property="BorderBrush" Value="Orange" /> <Setter Property="BorderThickness" Value="2" /> <Setter Property="Foreground" Value="Orange" /> </Style> </Page.Resources> <StackPanel VerticalAlignment="Center" HorizontalAlignment="Center"> <Button Content="Button" Style="{StaticResource PurpleStyle}" /> <Button Content="Button" /> </StackPanel> استفاده از استایل Based-on(بر پایه...) برای آسانتر ساختن استایل ها و حف و بهینه سازی برای استفاده مجدد از آن ها، شما می توانید استایل ها طوری بسازید که یک استایل از استایل دیگری ارث بری کند. شما از خاصیت BasedOn برای ساخت استایل ارث بری استفاده خواهید کرد. استایل هایی که از استیل های دیگر ارث بری می کنند باید TargetTypeـه آن مثل کنترلی که می خواهیم، یا کنترلی که از آن مشتق شده است باشد. برای مثال، اگر پایه یک استایل بر اساس ContentControl باشد، استایل هایی که از این استایل ارث بری می کنند می توانند Target(مقصد)ـی از ContentControl یا انواعی از کنترل ها باشد از ContentControl مشتق شده اند مانند Button و ScrollViewer. اگر یک مقدار بر پایه استایلی تنظیم نشود، ار استایل پایه ارث بری خواهد کرد. برای تغییر یک مقدار از استایل پایه، استایل based-on آن مقدار را بازنویسی خواهد کرد. در مثال بعدی یک دکمه و یک CheckBox را که از استایل پایه ارث بری می کنند نشان می دهد. Targetـه استایل پایه ContentControl می باشد، و خاصیت های Height(ارتفاع)، و Width(عرض) را تنظیم می کند. استایل هایی که بر پایه این استایل هستند CheckBox و Button را مورد هدف قرار می دهند که از ContentControl مشتق شده اند. استایل های based-on رنگ های متفاوتی را برای خاصیت های BorderBrush و Foreground تنظیم می کنند.(شما به طور معمول یک بردر را اطراف یک CheckBox قرار نمی دهید. در اینجا ما این کار را انجام دادیم تا به شما تاثیرات استایل دهی را نشان دهیم.) <Page.Resources> <Style x:Key="BasicStyle" TargetType="ContentControl"> <Setter Property="Width" Value="130" /> <Setter Property="Height" Value="30" /> </Style> <Style x:Key="ButtonStyle" TargetType="Button" BasedOn="{StaticResource BasicStyle}"> <Setter Property="BorderBrush" Value="Orange" /> <Setter Property="BorderThickness" Value="2" /> <Setter Property="Foreground" Value="Red" /> </Style> <Style x:Key="CheckBoxStyle" TargetType="CheckBox" BasedOn="{StaticResource BasicStyle}"> <Setter Property="BorderBrush" Value="Blue" /> <Setter Property="BorderThickness" Value="2" /> <Setter Property="Foreground" Value="Green" /> </Style> </Page.Resources> <StackPanel> <Button Content="Button" Style="{StaticResource ButtonStyle}" Margin="0,10" /> <CheckBox Content="CheckBox" Style="{StaticResource CheckBoxStyle}" /> </StackPanel> کتاب الکترونیک این درس پیوست شد. این درس به اتمام رسید، امیدوارم همچنان همراه ما باشید... . منبع: وین نویس Windows 10 Introduction S01E06.pdf
  20. آموزش استفاده از کنترل های رایج XAML استفاده ترکیبی از کنترل ها باعث می شود که شما بهتر با نحوه کارکرد کنترل ها آشنا شوید. پروژه جدید یکپارچه ایجادکنید و نام آنرا WN XAML Common Controls قرار دهید. در این پروژه قرار است با نحوه استفاده از کنترل های زیر آشنا شویم: ListView CheckBox RadioButton StackPanel ComboBox TextBox Image GridView Rectangle DatePicker TimePicker Pivot (تصویر بالا شکل برنامه است) صفحه MainPage.xaml را باز کنید و کدهای زیر را به جای <Grid.. </Grid> قرار دهید: <ListView x:Name="listView1" Background="White"> <CheckBox x:Name="checkBox1" Margin="5" Content="Check Box 1" /> <CheckBox x:Name="checkBox2" Margin="5" Content="Check Box 2" /> <StackPanel Orientation="Horizontal"> <RadioButton x:Name="radioButton1" Margin="5" Content="Radio Button 1" /> <RadioButton x:Name="radioButton2" Margin="5" Content="Radio Button 2" /> </StackPanel> <ComboBox x:Name="comboBox1" Margin="5"> <ComboBoxItem Content="ComboBox Item 1" /> <ComboBoxItem Content="ComboBox Item 2" /> <ComboBoxItem Content="ComboBox Item 3" /> <ComboBoxItem Content="ComboBox Item 4" /> <ComboBoxItem Content="ComboBox Item 5" /> </ComboBox> <TextBox x:Name="textBox1" Margin="5" Text="http://www.win-nevis.com" /> <Image x:Name="image1" Margin="5" Source="WinNevisLogo.png" Stretch="None" /> <GridView x:Name="gridView1" Margin="5"> <Rectangle x:Name="rectangle1" Fill="Red" Height="100" Width="100" /> <Rectangle x:Name="rectangle2" Fill="#FF00C5FF" Height="100" Width="100" /> <Rectangle x:Name="rectangle3" Fill="#FFFFD100" Height="100" Width="100" /> </GridView> <DatePicker x:Name="datePicker1" Margin="5" /> <TimePicker x:Name="timePicker1" Margin="5" /> </ListView> بپردازیم به کدها... <ListView x:Name="listView1" Background="White">… ListView در ابتدا کنترل ListView قرار دادیم تا همه ی کنترل ها به صورت لیستی عمودی در زیر هم قرار بگیرند. کنترل ListView بسیار پر کاربرد است، این کنترل دارای Property های خاصی است که چند نمونه را بیان می کنیم... . Items کالکشنی (لیست) است که کنترل ها را در خود جای می دهد، این پراپرتی از نوع ItemCollection است و می تواند تقریبا هر کنترل یا شئ ای را در خود جای دهد. این پراپرتی دارای توابعی است که از آنها می توان به Add, Remove, RemoveAt, Insert, Clear اشاره نمود. تابع Add برای اضافه کردن کنترل، Remove برای حذف کنترل چنانچه آن کنترل را در اختیار داشته باشیم، RemoveAt برای حذف کنترل بر اساس شناسه، Insert اضافه کردن آیتم در یک شاخص خاص(مثلا در ردیف 50)، Clear برای پاک کردن تمامی کنترل ها از لیست به کار می روند. SelectedIndex یا شاخص انتخاب شده، داده ی عددی از نوع integer است. این داده عددی را برمیگرداند که از آیتم انتخاب شده لیست ویو است. توجه داشته باشید که اندیس کنترل ها را بازگردانی می کند. SelectedItem آیتم انتخاب شده را بازگردانی می کند که با نوع object است یعنی پس از آن دریافت باید نوع آنرا خودمان تعیین کنیم. یعنی اگر در لیست بنده همه آیتم ها از نوع TextBox هستند، این کار را باید انجام دهیم: TextBlock selectedItem = listView1.SelectedItem as TextBlock; چنانچه مانند نمونه کدها، از چندین نوع شئ در لیست ویو استفاده می کنیم، نوع آیتم انتخاب شده را دریافت کنید و در شرطی آنرا بررسی کنید:[/size] if(listView1.SelectedItem.GetType() == typeof(TextBlock)) { // code } تابع GetType نوع هر داده ای را باز گردانی می کند که از نوع Type می باشد. کلمه کلیدی typeof نیز مشخص می کند که ما می خواهیم تایپ یا نوع داده را از نوعی که می خواهیم باشد. پس چنانچه آیتم انتخاب شده برابر با نوعی است که ما می خواهیم شرط درست است. SelectedItems در لیست ویو امکان انتخاب چند مورد وجود دارد، این پراپرتی توانایی بازگردانی لیست آیتم های انتخاب شده را داراست. SelectedMode تعیین می کند که آیا لیست ویو بتواند یک آیتم، چند آیتم را انتخاب کند یا اینکه حتی نتواند آیتمی را انتخاب کند. <CheckBox x:Name="checkBox1" Margin="5" Content="Check Box 1" /> <CheckBox x:Name="checkBox2" Margin="5" Content="Check Box 2" /> CheckBox جعبه انتخابی، اجازه می دهد کاربر گزینه ای را تیک بزند، اگر از چندین CheckBox در یک کنترل والد استفاده کنیم، هر چک باکس می تواند تیک (علامت) بخورد یا نخورد و وابسته با باقی چک باکس ها ندارد. پراپرتی IsSelected می تواند سه مقدار بگیرد، True و False و x:Null که تعیین می کند چک باکس ما کدام وضعیت را دارد. <StackPanel Orientation="Horizontal"> StackPanel این کنترل نیز مانند ListView است با اندکی تفاوت. پراپرتی Orientation تعیین می کند که کنترل هایی که درون این شئ قرار می گیرند به چه صورت اضافه شوند(عمودی یا افقی) به صورت پیشفرض اگر این پراپرتی را تعیین نکنیم کنترل هایی که اضافه می شوند به صورت عمودی زیر هم قرار می گیرند. در اینجا حالت افقی را قرار داده ایم تا دو کنترل RadioButton در کنار هم قرار بگیرند. <RadioButton x:Name="radioButton1" Margin="5" Content="Radio Button 1" /> <RadioButton x:Name="radioButton2" Margin="5" Content="Radio Button 2" /> RadioButton دکمه رادیویی نیز مانند CheckBox است اما با کمی تفاوت، چناچه یکی از آنها انتخاب شود، آیتم های دیگر خودکار تیک آنها برداشته می شود، برای مثال نمی توانیم هر دو مورد را علامت بزنیم، چنانچه اقدام به این کار کنیم، شئ دیگر خودکار علامتش برداشته میشود. البته این موضوع به والد آنها نیز وابسطه است. در اینجا شئ والد StackPanel است اگر در یک StackPanel دیگر دو دکمه رادیویی دیگر قرار دهیم، علامت زدن آنها به علامت زدن این دو ربطی نخواهد داشت. <ComboBox x:Name="comboBox1" Margin="5"> <ComboBoxItem Content="ComboBox Item 1" /> <ComboBoxItem Content="ComboBox Item 2" /> <ComboBoxItem Content="ComboBox Item 3" /> <ComboBoxItem Content="ComboBox Item 4" /> <ComboBoxItem Content="ComboBox Item 5" /> </ComboBox> ComboBox جعبه ترکیبی برای به نمایش در آوردن آیتم های فراوان است که یکی از آنها قابل انتخاب است. این کنترل می تواند هر نوع داده ای را در خود جای دهد. مانند لیست ویو SelectedIndex و SelectedItem دارد. <TextBox x:Name="textBox1" Margin="5" Text="http://www.win-nevis.com" /> TextBox جعبه متنی، این کنترل به کاربر این امکان را می دهد که بتواند چیزی را بنویسید.پراپرتی Text متن نوشته کاربر است. پراپرتی InputeScope به صورت پیشفرض اعداد، حروف، سمبل ها و... در تکست باکس قابل نمایش است، اما چنانچه می خواهید تکست باکس را اختصاص دهید مثلا برای فقط شماره ها، یا ایمیل، یا چت، بهتر از این پراپرتی استفاده کنید که دارای 42 گزینه برای انتخاب است! پراپرتی PlaceholderText نیز متنی را به نمایش در می آورد زمانی که هیچ چیزی در TextBox نوشته نشده باشد. مثلا همان type something در اکثر برنامه های چت. <Image x:Name="image1" Margin="5" Source="WinNevisLogo.png" Stretch="None" /> Image این کنترل تصاویر را به نمایش می گذارد. با استفاده از پراپرتی Source می توانیم محل عکس را تعیین کنیم، در اینجا عکسی با نام WinNevisLogo.png در قسمت روت پروژه وجود دارد که آنرا اینگونه تعریف کردیم. پراپرتی Stretch یا کِش آمدن تصویر، این امکان را می دهد که تصاویر را کِش آوریم یا اینکه تصویر اصلی با سایت اصلی را به نمایش در آوریم. <GridView x:Name="gridView1" Margin="5"> GridView این کنترل نیز مانند لیست ویو است با این تفاوت که کنترل ها در کنار هم به صورت افقی قرار می گیرند. چنانچه تعداد کنترل ها بیش از اندازه عرض صفحه باشد، کنترل ها به صورت افقی و عمودی در می آیند. <Rectangle x:Name="rectangle1" Fill="Red" Height="100" Width="100" /> <Rectangle x:Name="rectangle2" Fill="#FF00C5FF" Height="100" Width="100" /> <Rectangle x:Name="rectangle3" Fill="#FFFFD100" Height="100" Width="100" /> Rectangle کنترل رنگی با استفاده از پراپرتی Fill می توان رنگ یا تصویری را برای آن انتخاب نمود. <DatePicker x:Name="datePicker1" Margin="5"/> DatePicker انتخاب گر تاریخ، دارای پراپرتی Date از نوع DateTimeOffset است که کاربر می تواند تاریخی را انتخاب کند. <TimePicker x:Name="timePicker1" Margin="5" /> TimePicker انتخاب گر زمان، دارای پراپرتی Time از نوع TimeSpan است که کاربر می تواند زمانی را انتخاب کند. خب تا اینجا با 11 کنترل از 13 تایی که قرار بود آموزش بدهیم، آشنا شدید. برای دو کنترل دیگر دو پروژه مجزا ایجاد می کنیم. Pivot پروژه جدیدی یکپارچه ای به نام WN Pivot Sample ایجاد و صفحه MainPage.xaml را در آن باز کنید. در پنجره Toolbox دو بار روی کنترل Pivot کلیک کنید یا اینکه آنرا بکشید و در صفحه طراحی رها کنید تا این کنترل به صفحه اضافه شود: کنترل Pivot دارای خاصیتی به نام Title است که عنوان را مشخص می کند، معمولا نام برنامه را در این قسمت قرار می دهند. نیازی نیست حتما Pivot دارای عنوان باشد. عناصری که Pivot به عنوان تب قرار میگیرند PivotItem نام دارند. Pivot فقط می تواند PivotItem را به نمایش در آورد ما نمی توانیم جای PivotItem از Grid یا کنترل های دیگر استفاده کنیم. هر PivotItem دارای خاصیتی به نام Header است که نام یا آیکون تب را تعیین می کند. اگر بخواهیم جای نوشته از آیکون یا عکسی استفاده کنیم کافی است Header را پاک کرده و درون تَگِ PivotItem تگِ زیر را اضافه کنیم: <PivotItem.Header> <Image Source="WinNevisLogo.png" /> </PivotItem.Header> با این کار می توانیم عکسی را جای نوشته قرار دهیم: هر PivotItem می تواند یک Content ـی داشته باشد که به صورت پیشفرض Grid است چرا که میتواند تمامی اشیاء را درون خود جای دهد. روی <Grid/> PivotItem اول کلیک کنید و از ToolBox کنترل TextBlockـی را به درون قسمت طراحی اضافه کرده و نام آنرا برابر با Win-Nevis بگذارید. حال روی Gridـه PivotItemـه دوم کلیک کرده و کنترل دکمه ای درون آن بیاندازید و Content آنرا برابر با Click قرار دهید. چیزه خاص دیگری نیست که فعلا نیاز باشد راجع به این کنترل بدانید، پس به همین اکتفا می کنیم. نکته: قرار بود SplitView و ساخت منوی همبرگری رو هم توی این درس آموزش بدیم اما چون لازمه ی این کار چیزهای دیگری است ساخت منوی همبرگری به درس های بعد موکول می شود. کتاب الکترونیک + پروژه این درس پیوست شد. این درس به اتمام رسید، امیدوارم همچنان همراه ما باشید... . منبع: وین نویس Windows 10 Introduction S01E04.pdf WN Xaml Common Controls.zip
  21. سلام، مشکلی ایجاد نمیکنه فایل appxbundle معمولا برای بتا تستر ها مورد استفاده قرار میگیره اما استور هم قبولش می کنه. فایل appxupload مخصوص استور هست و زمانی که برنامه ای ایجاد شد بهتره که این فایل برای استور فرستاده بشه. این فایل حاوی سمبل های خطایابی (symbol debugging)برای کرش ریپورت ها(گزارش کرش ها) که برای رفع باگ برنامه نویس نیاز داره هست که این ها مورد نیاز برنامه ها نیز هستند. فایل appxupload همچنین دارای چند فایل فشرده با فرمت appxsym هست که این فایل سمبل های عمومی رو درون خودش ذخیره می کنه. درون فایل appxupload فایل appxbundle برنامه هم وجود داره. حجم فایل appxbundle به دلایلی که بالا گفته شد خیلی کمتر از فایل appxupload هست. موفق باشید.
  22. سلام من قبلا این کار رو برای پلیر های AVP و Ultra Player انجام داده. شما باید از پروژه ی FFMPEGInterop که مایکروسافت به عنوان یک Wrapper برای استفاده از FFMpeg ساخته استفاده کنید. این پروژه با زبان سی پلاس پلاس ساخته شده. https://github.com/Microsoft/FFmpegInterop اگه طبق گفته ی آدرس زیر عمل کرده باشید، پس باید فایل Solutionـه این پروژه نمونه رو بدون هیچ مشکلی باز کنید: https://trac.ffmpeg.org/wiki/CompilationGuide/WinRT پروژه نمونه در فایل Samples هست. اگه شما درست بیلد رو انجام داده باشید پس باید یکی از فایل های FFmpegSampleWin8.1.sln یا FFmpegSampleWin10.sln را بدون هیچ مشکلی با ویژوال استودیو باز کنید و میتونید بدون هیچ مشکلی اون رو اجرا کنید. (اولین Solution برای ویندوز 8.1 و دومین برای ویندوز 10 هست) اینم یه عکس از Solution ویندوز 8.1. پوشه MediaPlayerCS نمونه کد سی شارپی هست. شما باید توی همین Solution پروژه خودتون رو ایجاد کنید یا اینکه در یک Solution جدا این کار رو انجام بدید سپس پروژه FFMpegInterop رو به Solutionـه تون به عنوان یک پروژه اضافه کنید و سپس از طریق References پروژه خودتون اون رو به عنوان یک ریفرنس به پروژه اضافه کنید: راجع به کدک x265، این Wrapperـه که ساخته شده، درست از این کدک پشتیبانی نمیکنه. راه حلی هم هنوز ارائه نشده. موفق باشید.
  23. سلام اگه میشه بیشتر توضیح بدید که دقیقا می خواهید چیکار کنید.
  24. API موزیک استودیو پارسه نسخه 1.0.3 به روز رسانی شده در تاریخ 16 خرداد 1395 برابر 06/05/2016. شما می توانید این پروژه را در گیت هاب دنبال نمایید: https://github.com/ramtinak/ParseDevMusic این سرویس در حال حاضر برای تست ایجاد شده است. عکس هایی از پروژه نمونه: -------------- سرویس موزیک استدیو پارسه، کار را برای گرفتن اطلاعات از سایت های موزیک راحت می کند. با استفاده از این سرویس می توانید به راحتی برای سایت های موزیکی که میخواهید، نرم افزار بنویسید(فقط نام آن سایت را به ما معرفی کنید!) در حال حاضر این سرویس از 14 سایت پشتیبانی می کند. سایتهای فارس کیدز، فاز موزیک، ایران موزیک، نکس وان موزیک، موزیک ایرونی،پاپ موزیک، آهنگستان، پلی موزیک، موزیک باز، موزیک باران، تک ترانه و تهران موزیک می توانند تمامی پست ها، لینک های دانلود و همچنین جستجو کردن را در اختیار شما قرار دهند. با اسنفاده از دو سایت ZeneFarm و Mp3PM نیز می توانید به راحتی در سایت های جستجوی موزیک، به دنبال یک موزیک بگردید(لینک ها دانلود به صورت مستقیم هستند!) نکته: جستجو در سایت پلی موزیک در حال حاضر ممکن نیست! نکته جالب در مورد این سرویس این است که به صورت خودکار به روز رسانی می شود و نیازی به، به روز رسانی نرم افزار شما ندارد. برای مثال الان 14 سایت است ممکن فردا 20 سایت باشد! شما می توانید تمامی سایت ها را به راحتی در برنامه خود به کار ببرید. -------------- برای گرفتن لیست سایت ها از آدرس زیر استفاده کنید: http://api.win-nevis.com/sites.aspx مقدار بازگشتی به صورت JSON خواهد بود( در زیر می توانید نمونه و نوع متغیر ها را ببینید) [ { "Address": string, "IsRightToLeft": boolean, "IsSearcher": boolean, "Name": string }, { "Address": string, "IsRightToLeft": boolean, "IsSearcher": boolean, "Name": string } ] برای دریافت یک سایت از آدرس زیر استفاده کنید: http://api.win-nevis.com/index.aspx?siteAddress=ESMESITE کافیه نام سایت رو به جای کلمه ESMESITE قرار بدید تا لیست پست های اون سایت رو به شما بده: مثلا من میخوام سایت فارس کیدز رو بگیرم: http://api.win-nevis.com/index.aspx?siteAddress=farskids مقادیر بازگشتی به صورت JSON خواهد بود: [ { "ComingSoon": false, "Date": "23rd Mar 2016", "ImageUrl": "http:\/\/www.27farskids.com\/wp-content\/uploads\/2016\/03\/ddd-1-e1458748085612.jpg", "Name": "Matin M.T – Daghigheha", "Singer": null, "Song": null, "Type": "music", "Url": "http:\/\/www.27farskids.com\/music\/matin-m-t-daghigheha\/", "View": "42,178 Views" }, { "ComingSoon": false, "Date": "23rd Mar 2016", "ImageUrl": "http:\/\/www.27farskids.com\/wp-content\/uploads\/2016\/03\/Mahyar-Tn-Ft-Andish-Ro-Ravane-Hame-Chi.jpg", "Name": "Mahyar TN FT. Andish – Ro Ravane Hame Chi", "Singer": null, "Song": null, "Type": "music", "Url": "http:\/\/www.27farskids.com\/music\/mahyar-tn-ft-andish-ro-ravane-hame-chi\/", "View": "41,083 Views" } ] همونطور که مشاهده می کنید تمامی مقادیر بازگشتی پُر نخواهند بود و بعضی ها null هستند، این به خاطر این است که این مقادیر در یک سایت که آنها را دارد می تواند پُر باشد و در سایت دیگری که این اطلاعات را نمی دهد به صورت null خواهد بود. برای باز کردن صفحه دوم، سوم، چهارم و... از آدرس زیر استفاده کنید: http://api.win-nevis.com/index.aspx?siteAddress=ESMESITE&p=SHOMARESAFHE مثلا من می خوام صفحه چهارم از سایت فاز موزیک رو باز کنم: http://api.win-nevis.com/index.aspx?siteAddress=fazmusic&p=4 مقادیر بازگشتی به همان صورت خواهد بود که از http://api.win-nevis.com/index.aspx?siteAddress=fazmusic استفادهمی کنید. برای جستجو در یک سایت: http://api.win-nevis.com/index.aspx?siteAddress=ESMESITE&s=KALAMEJUSTJU مثلا من می خوام Saman jalili رو در سایت ایران موزیک جستجو کنم: http://api.win-nevis.com/index.aspx?siteAddress=iranmusic&s=saman%20jalili مقادیر بازگشتی به صورت JSON خواهد بود و مانند دو مقدار بازگشتی قبلی است. برای باز کردن صفحه دوم، سوم و... از یک جستجو کافی است از دستور زیر استفاده کنید: http://api.win-nevis.com/index.aspx?siteAddress=ESMESITE&s=KALAMEJUSTJU&p=SHOMARESAFHE اگر در مثال بالا بخواهیم صفحه دوم از جستجو را باز کنیم: http://api.win-nevis.com/index.aspx?siteAddress=iranmusic&s=saman%20jalili&p=2 مقادیر بازگشتی نیز مانند سه مورد قبل خواهد بود. برای گرفتن لینک دانلود، کافی است لینکی پستی که می خواهید را به این آدرس بفرستید: http://api.win-nevis.com/index.aspx?siteAddress=ESMESITE&getDownloadLink=POSTLINK برای مثال من آدرس یک پست از سایت فارس کیدز رو دارم و می خوام لینک های دانلود اون رو دریافت کنم: http://api.win-nevis.com/index.aspx?siteAddress=farskids&getDownloadLink=http://www.27farskids.com/music/ahmad-saeedi-yadet-biad/ مقادیر بازگشتی به صورت JSON خواهد بود: [ { "CommingSoon": false, "Dislike": null, "Like": null, "Name": "Ahmad Saeedi - Yadet Biad [320].mp3", "PostId": null, "Url": "http:\/\/dl3.27farskids.com\/R1\/Music\/95\/01\/03\/Ahmad%20Saeedi%20-%20Yadet%20Biad%20[320].mp3", "Views": null }, { "CommingSoon": false, "Dislike": null, "Like": null, "Name": "Ahmad Saeedi - Yadet Biad [128].mp3", "PostId": null, "Url": "http:\/\/dl3.27farskids.com\/R1\/Music\/95\/01\/03\/Ahmad%20Saeedi%20-%20Yadet%20Biad%20[128].mp3", "Views": null } ] تا اینجای کار برای سایت های موزیک بود، اما برای سایت هایی که مخصوص جستجوی موزیک هستند آدرس کمی متفاوت تر خواهد بود: برای جستجوی یک کلمه از آدرس زیر استفاده کنید: http://api.win-nevis.com/searcher.aspx?siteAddress=ESMESITE&s=KALAMEJUSTJU برای مثال میخواهیم saman jalili رو در سایت mp3pm جستجو کنیم: http://api.win-nevis.com/searcher.aspx?siteAddress=mp3pm&s=saman%20jalili برای باز کردن صفحه دوم، سوم و... از آدرس زیر استفاده کنید: http://api.win-nevis.com/searcher.aspx?siteAddress=ESMESITE&s=KALAMEJUSTJU&p=SHOMARESAFHE مثال: http://api.win-nevis.com/searcher.aspx?siteAddress=mp3pm&s=saman%20jalili&p=2 مقادیر بازگشتی به صورت JSON خواهد بود(مثال برای MP3PM) [ { "ComingSoon": false, "Date": null, "ImageUrl": null, "Name": null, "Singer": null, "Song": null, "Type": null, "Url": "http:\/\/cs1.mp3.pm\/download\/1446657\/S2VaYW9MTDBlazJYQ294UmdISjM1enVFM1VGdjVpbnVCSE5CSlArN3k1djlVMU02dkNVNWRxMmNpamRXYzAyc1Y3T3hVc2ZNYlZLY29WdlFPTXpKYllKWi81NGpRdW9vR2hwOWkwWlh1S0dnYWx2YTdhNUUxMlBoL3ZMbmtlQ1g\/Bahooneh_-_Saman_Jalili_(mp3.pm).mp3", "View": null, "Author": "Bahooneh", "Duration": "02:57", "Size": null, "Sound": "http:\/\/cs1.mp3.pm\/listen\/1446657\/S2VaYW9MTDBlazJYQ294UmdISjM1enVFM1VGdjVpbnVCSE5CSlArN3k1djlVMU02dkNVNWRxMmNpamRXYzAyc1Y3T3hVc2ZNYlZLY29WdlFPTXpKYllKWi81NGpRdW9vR2hwOWkwWlh1S0dnYWx2YTdhNUUxMlBoL3ZMbmtlQ1g\/Bahooneh_-_Saman_Jalili_(mp3.pm).mp3", "Title": "Saman Jalili", "TrackId": null }, { "ComingSoon": false, "Date": null, "ImageUrl": null, "Name": null, "Singer": null, "Song": null, "Type": null, "Url": "http:\/\/cs1.mp3.pm\/download\/6562930\/S2VaYW9MTDBlazJYQ294UmdISjM1enVFM1VGdjVpbnVCSE5CSlArN3k1dExrblJBd0diemtuL2l3dGFFV1BnaXNhM3hHZVdEM2daY3VrNnJzaXVBYVFrakNtOWpCeUM3Nm5KbnA1RC9QSjVCQWhSL1REbUxRYXQwV3JUaXp2dGc\/Saman_Jalili_-_Halam_Bade_2013_(mp3.pm).mp3", "View": null, "Author": "Saman Jalili", "Duration": "02:58", "Size": null, "Sound": "http:\/\/cs1.mp3.pm\/listen\/6562930\/S2VaYW9MTDBlazJYQ294UmdISjM1enVFM1VGdjVpbnVCSE5CSlArN3k1dExrblJBd0diemtuL2l3dGFFV1BnaXNhM3hHZVdEM2daY3VrNnJzaXVBYVFrakNtOWpCeUM3Nm5KbnA1RC9QSjVCQWhSL1REbUxRYXQwV3JUaXp2dGc\/Saman_Jalili_-_Halam_Bade_2013_(mp3.pm).mp3", "Title": "Halam Bade (2013)", "TrackId": null } ] مثال برای ZeneFarm: [{ "ComingSoon": false, "Date": null, "ImageUrl": "https:\/\/i1.sndcdn.com\/artworks-000081638230-64amys-large.jpg", "Name": "Saman Jalili - Khial", "Singer": null, "Song": null, "Type": null, "Url": "http:\/\/zenefarm.com\/download\/saman%20jalili\/153137046", "View": null, "Author": null, "Duration": " 0:03:46", "Size": " 3.5 MB", "Sound": null, "Title": null, "TrackId": "153137046" }, { "ComingSoon": false, "Date": null, "ImageUrl": "https:\/\/i1.sndcdn.com\/artworks-000032057296-ag3w04-large.jpg", "Name": "Mehdi Ahmadvand - Dooset Daram (Ft Saman Jalili)**cafemusic**", "Singer": null, "Song": null, "Type": null, "Url": "http:\/\/zenefarm.com\/download\/saman%20jalili\/63184038", "View": null, "Author": null, "Duration": " 0:03:16", "Size": " 6.5 MB", "Sound": null, "Title": null, "TrackId": "63184038" } ] نکته: برای سایت MP3PM متغیرهای Name, Url, Duration, Size, TrackId دارای مقدار هستند. نکته: برای سایت ZeneFarm متغیرهای Author, Title,ImageUrl,Size Url, Sound, Duration دارای مقدار هستند. نکته: سایت های موزیک نیازی به getDownloadLink ندارند چون تمامی لینک های اون ها به صورت مستقیم خواهد بود. نکته: شاید بگید لینک های سایت ZeneFarm که این صورت است: http://zenefarm.com/download/saman%20jalili/153137046 و این آدرس به صورت مستقیم نیست! اما اگر این لینک را با MediaElement یا Microsoft Edge یا IDM باز کنید خودکار شروع به دانلود میکند. سورس کد برای ویندوز/فون 8.1 و ویندوز 10 ضمیمه شد. منبع: وین نویس موفق باشید. APIForParseDevMusic.zip
  25. برای استفاده توسعه دهندگان خیر! اما با نرم افزار سورنا کاربرا می تونن جستجو کنن: www.soorena.in/soorena-uwp موفق باشید.