ملیساا 5015 اشتراک گذاری ارسال شده در 30 شهریور، ۱۳۸۹ مقالات آموزشی و کاربردی در زمینه wpf 2 لینک به دیدگاه
ملیساا 5015 مالک اشتراک گذاری ارسال شده در 30 شهریور، ۱۳۸۹ مقدمه: در ادامه مقالات آموزشي WPF ، در اين مقاله، نحوه ساخت دکمه هاي سفارشي را در تکنولوژي WPF به صورت ساده و روان آموزش خواهم داد. براي فهم مطالب اين مقاله و استفاده و بهره وري از آن، نيازمند است تا خواننده با مفاهيم کلي WPF از جمله تعريف Brush ها، Style ها، نحوه ايجاد Resource ها و استفاده از آن ها، آشنايي داشته باشد. در اين مقاله از Microsoft Visual Studio.Net 2008 ، نسخه Professional به روز رساني شده با Service Pack1 استفاده شده است. ايجاد پروژه: در جهت سهولت ياد گيري کاربر، سعي کرده ام که به ساده ترين شکل ممکن، اين آموزش را در اختيار شما قرار دهم. يک پروژه از نوع WPF Application ايجاد کنيد. نام دلخواهي را براي آن انتخاب نماييد. من در پروژه خودم آن را CustomButton ناميدم. در پنجره Solution Explorer بر روي Window1 راست کليلک نماييد و گزينه View Designer را کليک نماييد. مطمئن شويد که در قسمت کدهاي XAML مربوط به Window1 هستيد. کد XAML مربوط به Window1 به صورت زير مي باشد: xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="300" Width="300"> قبل ازتعريف کد هاي زير را وارد نماييد. کدهايي که براي ساخت دکمه خواهيم نوشت، در قسمت مربوط به Resource هاي Window1 قرار خواهند گرفت.(به نکته 1 آخر مقاله توجه نماييد.) براي ساخت دکمه سفارشي يک Style جديد ايجاد خواهيم کرد، و سپس با تعريف خاصيت Template، شکل و حالت دلخواه خود را به دکمه خواهيم داد. اما قبل از ايجادStyle جديد، تعاريف مربوط به Brush ها را خواهيم آورد. در قسمت Resource ها، کد هاي زير را وارد نماييد. امي که براي هر آيتم تعيين گرديده است، به خوبي بيانگر عملکر آن آيتم نيز ميباشد. به عنوان مثال، آيتم DisabledForeColor ، رنگ مربوط به دکمه را، در زماني که دکمه، در حالت Disable مي باشد، مشخص مي نماييد. به آيتم ButtonRotater توجه نماييد. اين آيتم يک RotateTransform مي باشد، که در زماني که دکمه توسط کاربر فشرده مي شود، باعث چرخش 180 درجه اي Border مربوط به دکمه مي شود که اين امر باعث مي شود، فشرده شدن دکمه توسط کاربر به خوبي مشخص شود و هنگام فشرده شدن، ظاهر دکمه با حالت پيش فرض آن متفاوت باشد. (قبل از خواند ادامه مطالب به نکته شماره 2 آخر مقاله توجه کنيد.) حال تعاريف مربوط به Style دکمه را در ادامه کد هاي فوق بنويسيد: کد: همانطور که در مقدمه مقاله آورده شد، خواننده بايد با مطالب تعريف Style ها، Trigger ها و ... آشنايي داشته باشد. به همين دليل در اين موارد توضيحي نخواهم داد. فقط به ذکر چند نکته در اکتفا خواهم کرد. هنکام تعاريف Style ها معمولا يک Key براي آن در نظر خواهيم گرفت. که با دستور زير مشخص مي شود: کد: x:Key="[style key name]" اما در Style فوق، من کليدي براي آن تعريف نکرده ام. اما تعريفي با عنوان کد: TargetType="{x:Type Button}" را آورده ام. در واقع با اين عمل، Style مربوطه به تمامي دکمه هاي درون Window1 (و اگر Style در app.xaml تعريف شده باشد؛ به تمام دکمه هاي به کار رفته در همه Window هاي برنامه) اعمال خواهد شد و نيازي به مقدار دهي خاصيت Style دکمه ها، نخواهد بود. براي کنترل رفتار دکمه، در حالت هاي مختلف، از Trigger ها و خواص مربوطه استفاده شده است. به عنوان مثال با تعريف Trigger زير رنگ پس زمينه و پيش زمينه دکمه در حالتي که دکمه به صورت Disable ميباشد را به رنگ هاي متناسب و تعريف شده در بالاي Style نسبت مي دهد. نکته 1: چنانچه بخواهيد، از دکمه سفارشي، در همه Windows هاي برنامه استفاده نماييد، تعاريف مربوطه را در قسمت Resource ها فايل App.xaml قرار دهيد. علاوه براين مي توانيد يک Resource Dictionary ايجاد کرده و توسط دستور Merge Dictionaries ، آن را به Resource هاي برنامه اضافه نماييد. من در برنامه هاييم اغلب ازاين حالت استفاده مي کنم به اين دليل که قابليت Reusable بودن بالايي را به همراه خواهد داشت. نکته 2: مي توانيد، براي ايجاد Brush ها نيز يک Resource Dictionary در نظر بگيريد، تعاريف مربوط به Brush ها و عناصري را که در قسمت هاي مختلف ساخت کنترل هاي سفارشي شما، مشترک مي باشند را در آن نوشته و سپس آن را هنکام ايجاد کنترل هاي سفارشي، به آنها اضافه نماييد. اين عمل در هنگام تعريف و ساخت Style ها که در آن ها اغلي عناصر از رنگ هاي يکساني بهره مي برند، باعث صرفه جويي در وقت و کئ نويسي سريع و همچنين خوانا تر مي شود و از نوشتن کد هاي تکراري جلوگيري مي کند. نکته3: دقت کنيد که زماني که يک Style جديد براي يکي از عنصرهاي موجود در Visual Studio تعريف مي نماييد، تمامي کنترل آن عنصر در اختيار شما خواهد بود و در واقع مي توانيد عناصر و کنترل هاي جديد با ظاهر دلخواه خود را به وجود آوريد. تبريک!!! شما اولين کنترل سفارشي خود را با موفقيت ايجاد کرديد و مي توانيد از ان در برنامه هايتان استفاده نماييد. شکل زير، نمونه هايي از دکمه ايجاد شده را در حالت هاي مختلف نشان مي دهد. اميدوارم که اين مقاله نيز، کمکي در جهت ارتقاء سطح دانش شما درزمينه برنامه نويسي و استفاده از تکنولوژي WPF در برنامه هايتان نمايد. خواهشمند است نظرات ،انتقادات و پيشنهادات خود را در رابطه با مقاله فوق از طريق ايميل با بنده در ميان گذاريد. برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام 3 لینک به دیدگاه
ملیساا 5015 مالک اشتراک گذاری ارسال شده در 30 شهریور، ۱۳۸۹ مقدمه: چند روز پیش دیدم که خیلیا دنبال Messagebox فارسی و Customizeشده هستند، گفتم یکی با WPF بنویسم تا دوستان با WPFو قابلیت هاش بیشتر آشنا بشن و ببینن چقدر لذت بخشه کار با WPF! توضیحات: این MessageBox هم میتونه فارسی باشه هم انگلیسی (پیش فرضش انگلیسی هست) و تقریبا همه قابلیت های Messagebox استاندارد رو داره + امکان تغییر Styleهمه قسمت هاش. چند نمونه عکس ازش: برای تغییر اسکین : WPFMessageBox.BackgroundBrush WPFMessageBox.BorderBrush WPFMessageBox.ButtonsStyle WPFMessageBox.TitleTextStyle WPFMessageBox.MessageTextStyle قبل از Show کردن، با مقدار دهی به هر کدوم از ویژگی های بالا میتونین اسکین اونو تغییر بدید. برای فارسی کردن : WPFMessageBox.IsPersian = true; بعد Show میکنید. اینا هم دو تا style مختلف که کد XAML ش تو فایل ضمیمه هم موجوده: 2 لینک به دیدگاه
ملیساا 5015 مالک اشتراک گذاری ارسال شده در 30 شهریور، ۱۳۸۹ مقدمه یک نمونه برنامه ساده با استفاده از الگوی طراحی MVVM و Entity Framework در WPF برای کار با دیتابیس، که اعمال Select, Insert, Update و Delete را با استفاده از ساختار های الگوی MVVM انجام می دهد. در صورتی که با الگوی MVVM آشنا نیستید مطالبی را که جناب آقای نصیری که در برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام در مورد MVVM قرار داده اند، مطالعه نمایید. توضیحات شمای کلی برنامه بصورت زیر است که نمایانگر لایه های مختلف MVVM می باشد. لایه DataAccess: شامل فایل دیتابیس است که یک جدول به نام Employee، دارای دو فیلد نام و ID می باشد. در این لایه می توان از انواع data source ها نظیر فایل های xml و ... نیز استفاده نمود. البته توجه داشته باشید که چنین لایه ای در الگوی MVVM نامبرده نشده است اما برای شفافیت بیشتر کدنویسی معمولا برنامه نویسانی که با MVVM سر و کار دارند، چنین اقدامی می کنند! لایه Model: در این لایه باید مدلی از داده ای که در DataAccess وجود دارد، ایجاد کنیم. با استفاده از Entity Framework، یک Entity Data Model خواهیم داشت که به عنوان مدلی آماده از لایه DataAccess می توان از آن نام برد. زیرا کدهای مورد نیاز برای ایجاد کلاس های Model را بصورت خودکار تولید می کند. برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام 001.[assembly: EdmSchemaAttribute()] 002. 003.namespace MVVM_EntityFramework.Model 004.{ 005. #region Contexts 006. 007. /// 008. /// No Metadata Documentation available. 009. /// 010. public partial class EmployeeRepository : ObjectContext 011. { 012. #region Constructors 013. 014. /// 015. /// Initializes a new EmployeeRepository object using the connection string found in the 'EmployeeRepository' section of the application configuration file. 016. /// 017. public EmployeeRepository() : base("name=EmployeeRepository", "EmployeeRepository") 018. { 019. this.ContextOptions.LazyLoadingEnabled = true; 020. OnContextCreated(); 021. } 022. 023. /// 024. /// Initialize a new EmployeeRepository object. 025. /// 026. public EmployeeRepository(string connectionString) : base(connectionString, "EmployeeRepository") 027. { 028. this.ContextOptions.LazyLoadingEnabled = true; 029. OnContextCreated(); 030. } 031. 032. /// 033. /// Initialize a new EmployeeRepository object. 034. /// 035. public EmployeeRepository(EntityConnection connection) : base(connection, "EmployeeRepository") 036. { 037. this.ContextOptions.LazyLoadingEnabled = true; 038. OnContextCreated(); 039. } 040. 041. #endregion 042. 043. #region Partial Methods 044. 045. partial void OnContextCreated(); 046. 047. #endregion 048. 049. #region ObjectSet Properties 050. 051. /// 052. /// No Metadata Documentation available. 053. /// 054. public ObjectSet Employees 055. { 056. get 057. { 058. if ((_Employees == null)) 059. { 060. _Employees = base.CreateObjectSet("Employees"); 061. } 062. return _Employees; 063. } 064. } 065. private ObjectSet _Employees; 066. 067. #endregion 068. #region AddTo Methods 069. 070. /// 071. /// Deprecated Method for adding a new object to the Employees EntitySet. Consider using the .Add method of the associated ObjectSet property instead. 072. /// 073. public void AddToEmployees(Employee employee) 074. { 075. base.AddObject("Employees", employee); 076. } 077. 078. #endregion 079. } 080. 081. 082. #endregion 083. 084. #region Entities 085. 086. /// 087. /// No Metadata Documentation available. 088. /// 089. [EdmEntityTypeAttribute(NamespaceName="dbModel", Name="Employee")] 090. [serializable()] 091. [DataContractAttribute(IsReference=true)] 092. public partial class Employee : EntityObject 093. { 094. #region Factory Method 095. 096. /// 097. /// Create a new Employee object. 098. /// 099. /// Initial value of the id property. 100. public static Employee CreateEmployee(global::System.Int32 id) 101. { 102. Employee employee = new Employee(); 103. employee.id = id; 104. return employee; 105. } 106. 107. #endregion 108. #region Primitive Properties 109. 110. /// 111. /// No Metadata Documentation available. 112. /// 113. [EdmScalarPropertyAttribute(EntityKeyProperty=false , IsNullable=true)] 114. [DataMemberAttribute()] 115. public global::System.String Name 116. { 117. get 118. { 119. return _Name; 120. } 121. set 122. { 123. OnNameChanging(value); 124. ReportPropertyChanging("Name"); 125. _Name = StructuralObject.SetValidValue(value, true); 126. ReportPropertyChanged("Name"); 127. OnNameChanged(); 128. } 129. } 130. private global::System.String _Name; 131. partial void OnNameChanging(global::System.String value); 132. partial void OnNameChanged(); 133. 134. /// 135. /// No Metadata Documentation available. 136. /// 137. [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] 138. [DataMemberAttribute()] 139. public global::System.Int32 id 140. { 141. get 142. { 143. return _id; 144. } 145. set 146. { 147. if (_id != value) 148. { 149. OnidChanging(value); 150. ReportPropertyChanging("id"); 151. _id = StructuralObject.SetValidValue(value); 152. ReportPropertyChanged("id"); 153. OnidChanged(); 154. } 155. } 156. } 157. private global::System.Int32 _id; 158. partial void OnidChanging (global::System.Int32 value); 159. partial void OnidChanged(); 160. 161. #endregion 162. 163. } 164. 165. #endregion 166. 167.} لایه View: برای View یک user control به نام EmployeeListView داریم که دارای یک DataGrid برای نمایش اطلاعات مشتریان، دو TextBox برای ورود اطلاعات و سه Button برای اعمال Insert و Update و Delete است. برای این کار از Command استفاده شده است. برای کد XAML آن به این شکل است: (به Binding ها دقت کنید) برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام 01.02. xmlns=" برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام " 03. xmlns:x=" برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام " 04. xmlns:mc=" برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام " 05. xmlns:d=" برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام " 06. mc:Ignorable="d" 07. d:DesignHeight="300" d:DesignWidth="300"> 08. 09. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. لایه ViewModel: بطور کلی برای هر View یک ViewModel باید باشد تا منطق آن را تولید نماید. در اینجا ما دو View داریم، user control و main wondow. کار main window نمایش View های دیگر در داخل خود است به همین دلیل جزو لایه View محسوب نمی شود. اما برای کنترل منطق آن باید یک ViewModel برای آن نیز داشته باشیم تا بتوانیم قابلیت نمایش View های مختلف در داخل آن را بوجود بیاوریم. کلاس ViewModelBase را نیز برای داشتن یک چارجوب کلی برای تمام ViewModel ایجاد می کنیم و همه ViewModel های موجود از آن ارث خواهند برد. ViewModelBase برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام 01.namespace MVVM_EntityFramework.ViewModel 02.{ 03. public abstract class ViewModelBase : INotifyPropertyChanged, IDisposable 04. { 05. protected ViewModelBase() 06. { 07. } 08. 09. public event PropertyChangedEventHandler PropertyChanged; 10. 11. protected virtual void OnPropertyChanged(string propertyName) 12. { 13. PropertyChangedEventHandler handler = this.PropertyChanged; 14. if (handler != null) 15. { 16. var e = new PropertyChangedEventArgs(propertyName); 17. handler(this, e); 18. } 19. } 20. 21. public void Dispose() 22. { 23. this.OnDispose(); 24. } 25. 26. protected virtual void OnDispose() 27. { 28. } 29. } 30.} MainWindowViewModel برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام 01.namespace MVVM_EntityFramework.ViewModel 02.{ 03. public class MainWindowViewModel : ViewModelBase 04. { 05. readonly EmployeeRepository _employeeRepository; 06. 07. ObservableCollection _viewModels; 08. 09. public MainWindowViewModel() 10. { 11. _employeeRepository = new EmployeeRepository(); 12. EmployeeListViewModel viewModel = new EmployeeListViewModel(_employeeRepository); 13. this.ViewModels.Add(viewModel); 14. } 15. 16. public ObservableCollection ViewModels 17. { 18. get 19. { 20. if (_viewModels == null) 21. { 22. _viewModels = new ObservableCollection(); 23. } 24. return _viewModels; 25. } 26. } 27. } 28.} EmployeeListViewModel به تعاریف Command ها توجه نمایید. برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام 001.namespace MVVM_EntityFramework.ViewModel 002.{ 003. class EmployeeListViewModel : ViewModelBase 004. { 005. 006. 007. readonly EmployeeRepository _employeeRepository; 008. 009. RelayCommand _insertCommand; 010. RelayCommand _updateCommand; 011. RelayCommand _deleteCommand; 012. 013. public Employee NewEmployee { get; set; } 014. 015. public ObservableCollection AllEmployees 016. { 017. get; 018. private set; 019. } 020. 021. public EmployeeListViewModel(EmployeeRepository employeeRepository) 022. { 023. if (NewEmployee == null) 024. NewEmployee = new Employee(); 025. if (employeeRepository == null) 026. { 027. throw new ArgumentNullException("employeeRepository"); 028. } 029. _employeeRepository = employeeRepository; 030. var tmp = from o in employeeRepository.Employees 031. 032. select o; 033. this.AllEmployees = new ObservableCollection(tmp.ToList()); 034. } 035. 036. protected override void OnDispose() 037. { 038. this.AllEmployees.Clear(); 039. } 040. 041. 042. 043. public ICommand InsertCommand 044. { 045. get 046. { 047. if (_insertCommand == null) 048. { 049. _insertCommand = new RelayCommand(param => this.InsertCommandExecute(), param => this.InsertCommandCanExecute); 050. } 051. return _insertCommand; 052. } 053. } 054. 055. public ICommand UpdateCommand 056. { 057. get 058. { 059. if (_updateCommand == null) 060. { 061. _updateCommand = new RelayCommand(param => this.UpdateCommandExecute(), param => this.UpdateCommandCanExecute); 062. } 063. return _updateCommand; 064. } 065. } 066. 067. public ICommand DeleteCommand 068. { 069. get 070. { 071. if (_deleteCommand == null) 072. { 073. _deleteCommand = new RelayCommand(param => this.DeleteCommandExecute(), param => this.DeleteCommandCanExecute); 074. } 075. return _deleteCommand; 076. } 077. } 078. 079. void InsertCommandExecute() 080. { 081. Employee emp = Employee.CreateEmployee(NewEmployee.id); 082. emp.Name = NewEmployee.Name; 083. _employeeRepository.Employees.AddObject(emp); 084. _employeeRepository.SaveChanges(); 085. var tmp = from o in _employeeRepository.Employees 086. 087. select o; 088. this.AllEmployees = new ObservableCollection(tmp.ToList()); 089. OnPropertyChanged("AllEmployees"); 090. } 091. 092. 093. bool InsertCommandCanExecute 094. { 095. get 096. { 097. var tmp = from o in _employeeRepository.Employees 098. where o.id == NewEmployee.id 099. select o; 100. if (tmp != null && tmp.Count() > 0) 101. { 102. return false; 103. } 104. return true; 105. } 106. } 107. 108. void UpdateCommandExecute() 109. { 110. var tmp = from o in _employeeRepository.Employees 111. where o.id == NewEmployee.id 112. select o; 113. tmp.First().Name = NewEmployee.Name; 114. _employeeRepository.SaveChanges(); 115. var tmp2 = from o in _employeeRepository.Employees 116. select o; 117. this.AllEmployees = new ObservableCollection(tmp2.ToList()); 118. OnPropertyChanged("AllEmployees"); 119. } 120. 121. 122. bool UpdateCommandCanExecute 123. { 124. get 125. { 126. var tmp = from o in _employeeRepository.Employees 127. where o.id == NewEmployee.id 128. select o; 129. if (tmp != null && tmp.Count() > 0) 130. { 131. return true; 132. } 133. return false; 134. } 135. } 136. 137. void DeleteCommandExecute() 138. { 139. var tmp = _employeeRepository.Employees.Single(o => o.id == NewEmployee.id); 140. _employeeRepository.Employees.DeleteObject(tmp); 141. _employeeRepository.SaveChanges(); 142. var tmp2 = from o in _employeeRepository.Employees 143. select o; 144. this.AllEmployees = new ObservableCollection(tmp2.ToList()); 145. OnPropertyChanged("AllEmployees"); 146. } 147. 148. 149. bool DeleteCommandCanExecute 150. { 151. get 152. { 153. var tmp = from o in _employeeRepository.Employees 154. where o.id == NewEmployee.id 155. select o; 156. if (tmp != null && tmp.Count() > 0) 157. { 158. return true; 159. } 160. return false; 161. } 162. } 163. } 164.} نکته : فایل App.cs را بصورت زیر تغییر می دهیم تا در زمان لود برنامه، محتوی main window را مشخص کنیم. main window قابلیت نمایش هر ViewModel ای را دارد و هر ViewModel دارای یک View است که در نهایت آن View دز main window نمایش داده می شود. برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام 01.namespace MVVM_EntityFramework 02.{ 03. /// 04. /// Interaction logic for App.xaml 05. /// 06. public partial class App : Application 07. { 08. protected override void OnStartup(StartupEventArgs e) 09. { 10. base.OnStartup(e); 11. MainWindow window = new MainWindow(); 12. var viewModel = new MainWindowViewModel(); 13. window.DataContext = viewModel; 14. window.Show(); 15. } 16. 17. } 18.} دقت کنید که در بخش XAML کلاس App قسمت مربوط به StaurtupUri را حذف کنید. و در آخر، کد XAML مربوط به MainWindow به شکل زیر خواهد بود: (به Resource های آن و Binding مربوط به ItemsSource دقت نمایید) برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام 01.02. xmlns=" برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام " 03. xmlns:x=" برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام " 04. xmlns:vm="clr-namespace:MVVM_EntityFramework.ViewModel" 05. xmlns:vw="clr-namespace:MVVM_EntityFramework.View" 06. Title="MainWindow" Height="350" Width="525" Background="#FFBCB4B4"> 07. 08. 09. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. نتیجه: MainWindow را به گونه ای طراحی کردیم که قادر به نمایش دادن ViewModel های مختلف باشد. هر ViewModel نیز یک منطق است که داده ها را از Model (یا DataAccess) گرفته و با استفاده از یک View، در MainWindow نمایش می دهد. توجه داشته باشید که هیچ کدام از فایل های XAML، دارای کدنویسی در Code-behind خود نیستند (به جز کد های پیش فرض خودشان) و این امر سبب می شود به راحتی بتوانید View های خود را به دلخواه و بدون نگرانی از به هم ریختن کدها تغییر دهید. تنها کار لازم، اعمال Binding ها در کد XAML است! برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام 2 لینک به دیدگاه
ملیساا 5015 مالک اشتراک گذاری ارسال شده در 30 شهریور، ۱۳۸۹ در بعضی برنامه های بنا به دلایلی برای توسعه دهنده هیچ اهمیتی ندارد که کاربر چند نمونه از برنامه را اجرا کند ولی اگر زمانی اجرای برنامه محدود بشود (به یک فرم )،برای این جور برنامه ها 3 نوع سناریو وجود دارد که به شرح آنها می پردازیم. اولین سناریو را می توان نرافزاری در نظر گرفت که فقط یک نمونه از آن اجرا می شود (فقط یک پنجره اصلی) و می تواند پارامتر های را در هنگام اجرا بپذیرد به طور مثال برنامه ی مثل ویندوز مدیا پلیر و سناریو دیگر این است که در واقع از نرم افزار فقط یک نمونه اجرا می شود ولی دارای تعدادی پنجره مختلف است (Document Base) از این برنامه ها می توان MS Word رو مثال زد که کاربر شاید فکر بکند چند نمونه از برنامه را اجرا کرده در صورتی که فقط یک نمونه از برنامه اجرا شده و پنجره های مختلف را مدیریت می کند که از افزوده شدن سربار اضافی به سیستم جلوگیری می کند و سناریو آخری که می توان در نظر داشت برنامه ای که فقط یک نمونه از ان اجرا می شود (فقط یک پنجره اصلی) و هیچ پارامتر ورودی نمی پذیرد.البته سناریوهای دیگری را نیز می توان نام برد ولی ما به همین سه سناریو اکتفا می کنیم برای پیاده سازی این قبیل نرم افزار ها راه حل های زیادی وجود دارد که هر کدام کم وبیش این قابلیت را به ما می دهند ولی ما قصد بررسی روشی رو داریم که در آن بتوان هر سه سناریو را پیاده سازی کرد مثلا برای این منظور از Mutex استفاده می کنند که در آن نمی توان سناریویی اول و دوم را پیاده سازی کرد و یا پردازش ها بررسی می کنند که باز هم شامل سناریویی 1و2 نمی شود کد: ( 1 ) با ارائه شدن WPF توسط مایکرسافت برای این منظور در C# هیچ تمهیداتی پیش بینی نشده بود ولی تیم توسعه VB.NET این امکان را فراهم کرده بودند که ما نیز قصد استفاده از آن را در C# داریم در VB.NET در فضای نام کلاسی وجود دارد به نام برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام که این امکان را برای ما فراهم می کندو ما با مشتق کردن کلاسی از این کلاس می توانیم موفق به پیاده سازی هر سه سناریو بشویم. این کلاس سه عضو را پیاده سازی می کند که از آنها برای این منظور استفاده می کنیم برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام : یک خصیصه است و مشخص می کند که آیا از این برنامه فقط یک نمونه اجرا بشود یا نه؟ که ما آن را در سازنده کلاس با true مقدار دهی می کنیم. برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام : این رویداد زمانی رخ می دهد که اولین نمونه از برنامه در حال ساخته شدن است و می توانیم به آرگومان های ورودی دسترسی داشته باشیم( StartupEventArgs ). برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام : همانطور که از نامش پیداست این زمانی رخ می دهد که نمونه دیگری از برنامه در حال ساخته شدن باشد.در این رویداد نیز می توان به آرگومان های ورودی دسترسی داشته باشیم ( StartupNextInstanceEventArgs ) خوب برای این که بتوانید به این کلاس دسترسی پیدا کنید با ید یک ارجاع به اسمبلی Microsoft.VisuaBasic.dllدر پروژه داشته باشید. در اینجا ما سناریوی دوم را بررسی می کنیم که مشکلترین آنهاست و توسعه دهندگان اکثرا با پیاده سازی آن مشکل دارند ابتدا یک کلاس را از WindowsFormsApplicationBase مشتق می کنیم و پیاده سازی زیر را انجام می دهیم کد : ( 2 ) این کلاس یک نمونه از شی Application مورد نظر ما را نگهداری می کند (App) و در رویداد OnStartup یک نمونه از شی Application ساخته می شود و در رویداد OnStartNextInstance پنجره اصلی برنامه با نام MyWindow فعال می شود و سپس آرگومان های ورودی پردازش می شوند .توجه کنید که این قاعده کلی است و اگر این قسمت را متوجه شوید 70% راه را طی نموده اید. حال ما قسمت کد نویسی شی Application را بررسی می کنیم (نه کد XAML) کد : ( 3 ) در این کلاس تابع ProcessArgs آرگومان های ورودی را گرفته و تجزیه می کند سپس اطلاعات را به تابعی با همین نام در شئ MyWindow تحویل می دهد (ورودی ها در ادامه بررسی خواهند شد) حال نگاهی به پیاده سازی MyWindow می اندازیم کد : ( 4 ) در این پنجره که به عنوان پنجره اصلی برنامه است شما می بایست آرگومان های ورودی را بررسی (Parse) کنید و نمایش صحیحی رو بسته به برنامه در اختیار کاربر قرار دهید که ما در اینجا وقت به نمایش آرگومان های ورودی بسنده می کنیم. ورودی اول آرگومتن های ورودی است و ورودی دوم مشخص می کند که آیا نمونه اول و اصلی است یا نمونه دیگر (اجرای اول با دیگر) توجه کنید که تا این جا این راه حل برای یک Build از برنامه کار می کند واگر بخواهید که برای انواع Build های نرم افزار در یک سیستم جواب بدهد باید در فایل Assembly.cs پروژه خود یک اتریبیوت به نام GuidAttribute را بیفزایید چون اگر Guidرو مقداردهی نکنید دات نت در هر بار Build یک Guid به آن اختصاص می دهدو در Build های مختلف برنامه نمی توانید یک فرم واحد داشته باشید. کد: ( 4 ) حاصل برنامه بالا با توجه به ورودی های مختلف در تصویر زیر مشخص است برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام منابع : من اول این نکته رو در کتاب برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام خوندم بعد از برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام تکمیلش کردم. فایل پروژه را می توانید از { برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام } دریافت کنید. کدها به پیوست میباشد . برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام برای مشاهده این محتوا لطفاً ثبت نام کنید یا وارد شوید. ورود یا ثبت نام 1 لینک به دیدگاه
ارسال های توصیه شده