ASP.NET MVC #12
در قطعه کد
@model bool <p>@Html.RadioButton("", false, !Model) Female</p> <p>@Html.RadioButton("", true, Model) Male</p>
بعدش اینکه برای فهم قطعه کد زیر باید با چه مفاهیمی آشنا باشیم (پر کردن DropDown)
@model Enum @Html.DropDownListFor(m => m, Enum.GetValues(Model.GetType()) .Cast<Enum>() .Select(m => { string enumVal = Enum.GetName(Model.GetType(), m); return new SelectListItem() { Selected = (Model.ToString() == enumVal), Text = enumVal, Value = enumVal }; }))
روی tblNews کلیک کرده آنرا بکشید و روی فرم رها کنید. آنگاه ظاهر فرم و چیدمان کنترلها را تنظیم کنید و دو دکمه ذخیره و لغو برابر با شکل در فرم ایجاد کنید:
کد رویداد دو دکمه را اینگونه بنویسید:
private void btnCancel_Click(object sender, EventArgs e) { this.Close(); } private void btnSave_Click(object sender, EventArgs e) { this.DialogResult = System.Windows.Forms.DialogResult.OK; }
در پایین فرم روی tblNewsBindingSource کلیک کنید و از قسمت Properties ویژگی Modifiers آنرا برابر با Public کنید.
روی Combobox کلیک کنید، سپس ویژگی DataBinding -> Text آنرا خالی کنید. سپس روی فلش بالای Combobox دسته خبر کلیک کنید و تنظیمات آنرا مانند شکل زیر انجام دهید.
برای پرشدن آن کد زیر را در رویداد Load فرم اینگونه بنویسید:
private void frmAddEditNews_Load(object sender, EventArgs e) { MyNewsService.MyNewsServiceClient MyNews = new MyNewsService.MyNewsServiceClient(); tblCategoryIdComboBox.DataSource = MyNews.GetAllCategory(); }
به فرم اصلی بازگردید و برای رویداد دکمهی ویرایش چنین بنویسید:
private void btnEdit_Click(object sender, EventArgs e) { if (tblNewsDataGridView.CurrentRow == null) { MessageBox.Show("سطری برای ویرایش انتخاب کنید"); } else { //tblNews news = tblNewsDataGridView.CurrentRow.DataBoundItem as tblNews; tblNews news = MyNews.GetNews(Convert.ToInt32(tblNewsDataGridView.CurrentRow.Cells["tblNewsId"].Value)); frmAddEditNews frmAdd = new frmAddEditNews(); frmAdd.tblNewsBindingSource.DataSource = news; if (frmAdd.ShowDialog() == DialogResult.OK) { MyNews.EditNews(news); tblNewsBindingSource.DataSource = MyNews.GetAllNews().Select(p => new { p.tblNewsId, p.tblCategory.CatName, p.Title, p.Description, RegDate = MiladiToShamsi(p.RegDate) }); } } }
در صورتی که متد GetAllNews را به صورت ساده به ویژگی DataSource دیتاگرید نسبت داده بودیم میتوانستید از کد زیر برای مقداردهی به متغیر news بهره ببریم. ولی در حال حاضر این خط کد پیغام خطا میدهد. البته راههای دیگری برای حل این مشکل وجود دارد که در این درس قصد پرداختن به آنرا ندارم.
tblNews news = tblNewsDataGridView.CurrentRow.DataBoundItem as tblNews;
کد مربوط به رویداد دکمهی افزودن و حذف را نیز به صورت زیر بنویسید:
private void btnAdd_Click(object sender, EventArgs e) { tblNews news = new tblNews(); frmAddEditNews frmAdd = new frmAddEditNews(); frmAdd.tblNewsBindingSource.DataSource = news; if (frmAdd.ShowDialog() == DialogResult.OK) { MyNews.AddNews(news); tblNewsBindingSource.DataSource = MyNews.GetAllNews().Select(p => new { p.tblNewsId, p.tblCategory.CatName, p.Title, p.Description, RegDate = MiladiToShamsi(p.RegDate) }); } } private void btnRemove_Click(object sender, EventArgs e) { if (MessageBox.Show("آیا با حذف این سطر اطمینان دارید؟","هشدار",MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.Yes) { MyNews.DeleteNews(Convert.ToInt32(tblNewsDataGridView.CurrentRow.Cells["tblNewsId"].Value)); tblNewsBindingSource.DataSource = MyNews.GetAllNews().Select(p => new { p.tblNewsId, p.tblCategory.CatName, p.Title, p.Description, RegDate = MiladiToShamsi(p.RegDate) }); } }
برنامه را اجرا کنید. کار ما کم و بیش به پایان رسیده است. شما یک پروژهی ویندوز ساده با استفاده از WCF ای که از Entity Framework برای اتصال به پایگاه داده بهره میبرد؛ ایجاد کردید. WCF بسیار گستردهتر از این است و در اینجا تنها به بخشی از آن پرداختیم. احتمالاً در صورت استقبال خوانندگان در آینده دربارهی تنظیمات ریز WCF برای امنیت، سرعت، محدودیت و استفاده در محیطهای مختلف خواهم نوشت.
شاد و پیروز باشید.
Sqlite دیتابیس مناسبی برای برنامههای چندسکویی است و عموما به عنوان اولین گزینه استفاده میشود. برای کار با این دیتابیس، ما از ماژول sql.js که یکی از ماژولهای معروف در جاوااسکریپت است، استفاده میکنیم. برای نصب آن از طریق npm، به شکل زیر اقدام میکنیم:
npm install sql.js --save
const{app,BrowserWindow}=require("electron"); let win; function onLoad() { win=new BrowserWindow({ width:800, height:600 }); win.loadURL(`file://${__dirname}/index.html`); } app.on("ready",onLoad());
var path=require("path"); path.exists('filepath",(status)=> { .... }); var status=path.existsSync("file"); //=============================== var fs=require("fs"); fs.exists('filepath",(status)=> { .... }); var status=path.existsSync("file");
fs.stat('foo.txt', function(err, stat) { if(err == null) { console.log('فایل موجوده'); } else if(err.code == 'ENOENT') { // فایل وجود نداره fs.writeFile('log.txt', 'Some log\n'); } else { //خطای دیگری رخ داده است } });
try { stats = fs.statSync(path); console.log("File exists."); } catch (e) { console.log("File does not exist."); }
const fs = require('fs'); const sql = require('sql.js'); dbPath = './mydb.sqlite'; dbExists=false; try { dbExists = fs.statSync(dbPath); } catch (e) { } if(!dbExists) { //create Database var sqlStr=fs.readFileSync("./sql.txt"); var db = new sql.Database(); db.run(String(sqlStr)); //write to disk var data=db.export(); var buffer=new Buffer(data); fs.writeFileSync(dbPath,buffer); } else{ var buffer = fs.readFileSync(dbPath); var db = new sql.Database(buffer); }
CREATE TABLE numbers ( id INT PRIMARY KEY UNIQUE NOT NULL, fname VARCHAR (20) NOT NULL, lname VARCHAR (30) NOT NULL, number VARCHAR (15) NOT NULL ); insert into numbers values(1,'ali','yeganeh','03111223344'); insert into numbers values(2,'xxx','yyy','45454555');
بعد از آن نیاز است تا دیتابیس در دسترس Render Processها قرار بگیرد که در مقاله "شیوه کدنویسی در الکترون " در مورد global صحبت کردهایم و نحوه استفاده از آن را فرا گرفتیم:
global.db=db;
در پایان اجرای برنامه لازم است که دیتابیس توسط دستور close بسته شود. سپس کد زیر را در رویداد windows-all-closed مینویسیم:
app.on('window-all-closed', () => { db.close(); if (process.platform !== 'darwin') { app.quit(); } });
(چند مورد خارج از بحث): کد بعدی که مورد استفاده قرار گرفته است و در مقالات قبلی در مورد آن صحبت نکردهایم این است که در سیستمهای مک، وضعیت به این قرار است که اگر شما برنامه را ببیندید، آن برنامه بسته نشده و در پس زمینه فعال است و میتوانید آن را از طریق dock اطراف صفحه، مجددا فعال کنید. ولی با نوشتن کد بالا، ما این وضعیت را اعلام کردهایم که اگر تمامی پنجرهها بسته شدند، کل برنامه را ببند.
همچنین بسیار خوب است که کد زیر را هم همیشه اضافه کنید:
win.on('closed', () => { win = null; });
پس اگر این کد را نوشتید، وضعیت سیستم عامل مک را به خاطر داشته باشید و مجبور هستید کد زیر را نیز اضافه کنید:
app.on('activate', () => { if (win === null) { createWindow(); } });
بعد از اینکه دیتابیس را به شیء global دادیم، در صفحه html کد زیر را وارد میکنیم:
<html> <head> <script src="./jquery.min.js"></script> <link href="./bootstrap-3.3.6-dist/css/bootstrap.min.css" rel="stylesheet"></link> <meta charset="utf-8"> <title></title> <script> const {remote}=require("electron"); let db=remote.getGlobal("db"); </script> </head> <body> <table id="people" class="table table-hover table-striped"> <th> <tr> <td>First Name</td> <td>last Name</td> <td>Phone Number</td> </tr> </th> <tbody> </tbody> </table> </body> </html>
$(document).ready(()=> { //show data var tableBody=$("#people"); db.each("select * from numbers",(row)=>{ let rowTemplate=`<tr><td>${row.fname}</td><td>${row.lname}</td><td>${row.number}</td></tr>`; tableBody.append(rowTemplate); });
حال وقت آن رسیده است که خروجی کار را ببینیم. پس کد npm start را اجرا میکنیم. همانطور که میبینید خروجی به راحتی نمایش داده میشود. در مقاله بعدی بیشتر در این مورد صحبت میکنیم.
آپلود فایل توسط فرمهای پویای jqGrid
if (imageName == null) return Json(new { success = false }, JsonRequestBehavior.AllowGet);
return Json(new { success = false }, "text/html", JsonRequestBehavior.AllowGet);
public class ItemInfo { public string ItemCode { get; set; } public string Description { get; set; } public decimal Price { get; set; } } public class OutOfStockException : Exception { public OutOfStockException() : base() { } public OutOfStockException(string message) : base(message) { } }
public sealed class LookupItem : CodeActivity { // Define an activity input argument of type string public InArgument<string> ItemCode { get; set; } public OutArgument<ItemInfo> Item { get; set; } // If your activity returns a value, derive from CodeActivity<TResult> // and return the value from the Execute method. protected override void Execute(CodeActivityContext context) { // Obtain the runtime value of the Text input argument ItemInfo i = new ItemInfo(); i.ItemCode = context.GetValue<string>(ItemCode); switch (i.ItemCode) { case "12345": i.Description = "Widget"; i.Price = (decimal)10.0; break; case "12346": i.Description = "Gadget"; i.Price = (decimal)15.0; break; case "12347": i.Description = "Super Gadget"; i.Price = (decimal)25.0; break; } context.SetValue(this.Item, i); } }
item.ItemCode
نکته : از کلاس Code Activity برای ارسال و دریافت مقادیر به درون Workflow استفاده میشود.
new OutOfStockException("Item Code"+item.ItemCode)
من 2 ماهی هست که شروع کردم به یادگیری mvc و امروز رسیدم به این قسمت ، برنامه رو مثل شما نوشتم و یه کم مشکل دارم: قسمتی که باید dropdownList دوم که گروه است رو پر کنه کار نمیکنه! وارد کد jquery میشه و حتی متد SelectCategory رو هم فراخوانی میکنه اما dropdownList دومم رو خالی بر میگردونه!
export function error(){ alert('oops, an error'); }
var module = await JS.InvokeAsync<IJSObjectReference>("import", "./Panel.razor.js"); await module.InvokeVoidAsync("error");
Pages/Panel.razor Pages/Panel.razor.js Pages/Panel.razor.css
_module = await JS.InvokeAsync<IJSObjectReference>("import", "./_content/RazorClassLibrary/componentName.razor.js");
export function showPrompt(message) { return prompt(message, 'Type anything here'); }
@page "/call-js-example-6" @implements IAsyncDisposable @inject IJSRuntime JS <h1>Call JS Example 6</h1> <p> <button @onclick="TriggerPrompt">Trigger browser window prompt</button> </p> <p> @result </p> @code { private IJSObjectReference? module; private string? result; protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { module = await JS.InvokeAsync<IJSObjectReference>("import", "./scripts.js"); } } private async Task TriggerPrompt() { result = await Prompt("Provide some text"); } public async ValueTask<string?> Prompt(string message) => module is not null ? await module.InvokeAsync<string>("showPrompt", message) : null; async ValueTask IAsyncDisposable.DisposeAsync() { if (module is not null) { await module.DisposeAsync(); } } }