ورود

View Full Version : آموزش: طراحی و ساخت منو داینامیک در MVC توسط EF Code First



ali_autumnal
چهارشنبه 22 خرداد 1392, 18:23 عصر
با سلام

بدون مقدمه بریم سر اصل مطلب

می خواهیم منوی داینامیکی ایجاد کنیم و در کل پروژه استفاده کنیم

برای اینکار ابتدا مدل مورد نظر رو به شرح زیر ایجاد می کنیم:


using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;


مدل:


/// <summary>
/// مدلی برای ایجاد و مدیریت منو داینامیک در صفحات
/// </summary>
public class MenuModel
{
[Key]
[Display(Name = "کد")]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption .Identity)]
public int MenuId { get; set; }

[Required]
[Display(Name = "عنوان")]
[DataType(DataType.Text)]
[MaxLength(35)]
public string Name { get; set; }

[Display(Name = "توضیحات")]
[DataType(DataType.MultilineText)]
[MaxLength(50)]
public string Description { get; set; }

[Required]
[Display(Name = "کد صفحه")]
public int PageId { get; set; }

[Display(Name = "تاریخ ایجاد")]
[DataType(DataType.DateTime)]
public DateTime CreateDate { get; set; }

[Display(Name = "تاریخ آخرین ویرایش")]
[DataType(DataType.DateTime)]
public DateTime UpdateDate { get; set; }

[Required]
[Display(Name = "وضعیت")]
public bool IsActive { get; set; }

[Required]
[Display(Name = "زیر مجموعه")]
public int ParentId { get; set; }

[Required]
[Display(Name = "ترتیب")]
public int SortId { get; set; }
}



مدل مربوطه را در پوشه Models با نام MenuModels ذخیره می کنیم

سپس پوشه ای در ریشه پروژه با نام DataLayer ایجاد می کنیم.

پس از آن کلاسی با نام MenuDbContext ایجاد می کنیم
و داخل آن کلاس زیر را می نویسیم:

using System.Data.Entity;



public class MenuDbContext:DbContext
{
public DbSet<DynamicMenu.Models.MenuModel> MenuModels { set; get; }
}


سپس به فایل Global.asax مراجعه کرده namespace

using System.Data.Entity;

و پس از


protected void Application_Start()
{


کد زیر را اضافه می کنیم

Database.SetInitializer(new DropCreateDatabaseIfModelChanges<DynamicMenu.DataLayer.MenuDbContext>());


کلاس دیگری با نام SampleModels در پوشه Models ایجاد می کنیم.

مدل های زیر را داخل این فایل می نویسیم


public class ConstModels
{
public IEnumerable<MenuModel> MenuViewModels { set; get; }
}

public class HomePageViewModel : ConstModels
{

}

public class AboutPageViewModel : ConstModels
{

}

public class ContactPageViewModel : ConstModels
{

}

public class Menus : ConstModels
{
public IEnumerable<MenuModel> Menuslist { set; get; }
public MenuModel MenuHeaderModel { set; get; }
}


پروژه را یکبار Rebuild می کنیم.

سپس بر روی پوشه کنترلر کلیک راست کرده و گزینه Add سپس گزینه Controller را انتخاب می کنیم

در Controller Name :
MenuController
می نویسیم

در Template گزینه:
MVC controller with read/write actions and views, using Entity Framwork

را انتخاب می کنیم سپس در Model class گزینه MenuModel را انتخاب می کنیم

سپس در Data context class گزینه MenuDbContext را انتخاب می کنیم.

در نهایت برروی گزینه Add کلیک می کنیم

داخل کنترلر منو رفته و Action Index رو به شرح زیر اصلاح می کنیم

public ActionResult Index()
{
var item = new DynamicMenu.Models.Menus
{
Menuslist = db.MenuModels.ToList(),
MenuViewModels = db.MenuModels.Where(p => p.IsActive == true).OrderByDescending(p => p.SortId).ToList()
};
return View(item);
}


سپس به HomeController رفته و آن را به شرح زیر اصلاح می کنیم:

public ActionResult Index()
{
ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";
var item = new DynamicMenu.Models.HomePageViewModel
{
MenuViewModels = context.MenuModels.Where(p => p.IsActive == true).OrderByDescending(p => p.SortId).ToList()
};
return View(item);
}

public ActionResult About()
{
ViewBag.Message = "Your app description page.";

var item = new DynamicMenu.Models.AboutPageViewModel
{
MenuViewModels = context.MenuModels.Where(p => p.IsActive == true).OrderByDescending(p => p.SortId).ToList()
};
return View(item);
}

public ActionResult Contact()
{
ViewBag.Message = "Your contact page.";

var item = new DynamicMenu.Models.ContactPageViewModel
{
MenuViewModels = context.MenuModels.Where(p => p.IsActive == true).OrderByDescending(p => p.SortId).ToList()
};
return View(item);
}


سپس به پوشه View و سپس در داخل Shared یک PartialView ایجاد می کنیم . نام آنرا MenuPartial_ می گذاریم

سپس در داخل آن تابع بازگشتی زیر را می نویسیم:


@model DynamicMenu.Models.ConstModels

@helper MenuItems(int id, bool startTag, bool FirstTag)
{
var ParentMenu = Model.MenuViewModels.Where(p => p.ParentId == id).OrderByDescending(x => x.SortId);
if (ParentMenu != null && ParentMenu.Count() > 0)
{
if (startTag)
{
<ul id="nav">
@foreach (var item in ParentMenu)
{
<li title="@item.Description" class="first">
@switch (item.PageId)
{
case 1:
@Html.ActionLink(item.Name, "Index", "Home")
break;
case 2:
@Html.ActionLink(item.Name, "About", "Home")
break;
case 3:
@Html.ActionLink(item.Name, "Contact", "Home")
break;
case 4:
@Html.ActionLink(item.Name, "Index", "Menu")
break;
default:
@Html.ActionLink(item.Name, "Content/" + item.PageId, "Pages")
break;
}
@MenuItems(item.MenuId, false, true)
</li>
}
</ul>
}
else
{
if (FirstTag)
{
<ul class="nav first">
@foreach (var item in ParentMenu)
{
<li title="@item.Description" class="first">
@switch (item.PageId)
{
case 1:
@Html.ActionLink(item.Name, "Index", "Home")
break;
case 2:
@Html.ActionLink(item.Name, "About", "Home")
break;
case 3:
@Html.ActionLink(item.Name, "Contact", "Home")
break;
default:
@Html.ActionLink(item.Name, "Content/" + item.PageId, "Pages")
break;
}
@MenuItems(item.MenuId, false, false)
</li>
}
</ul>
}
else
{
<ul class='nav'>
@foreach (var item in ParentMenu)
{
<li title="@item.Description" class="first">
@switch (item.PageId)
{
case 1:
@Html.ActionLink(item.Name, "Index", "Home")
break;
case 2:
@Html.ActionLink(item.Name, "About", "Home")
break;
case 3:
@Html.ActionLink(item.Name, "Contact", "Home")
break;
default:
@Html.ActionLink(item.Name, "Content/" + item.PageId, "Pages")
break;
}
@MenuItems(item.MenuId, false, false)
</li>
}
</ul>
}
}
}
}
<div id="MenuSection">

@MenuItems(0, true, true)

</div>



سپس به Layout_ رفته و تکه کد زیر را به آن اضافه می کنیم


@Html.Partial("_MenuPartial")


سپس کد Css زیر را به Site.css اضافه کنید

html {
background-color: #e2e2e2;
margin: 0;
padding: 0;
}

body {
background-color: #fff;
border-top: solid 10px #000;
color: #333;
font-size: .85em;
font-family: "Segoe UI", Verdana, Helvetica, Sans-Serif;
margin: 0;
padding: 0;
}

a {
color: #333;
outline: none;
padding-left: 3px;
padding-right: 3px;
text-decoration: underline;
}

a:link, a:visited,
a:active, a:hover {
color: #333;
}

a:hover {
background-color: #c7d1d6;
}

header, footer, hgroup,
nav, section {
display: block;
}

mark {
background-color: #a6dbed;
padding-left: 5px;
padding-right: 5px;
}

.float-left {
float: left;
}

.float-right {
float: right;
}

.clear-fix:after {
content: ".";
clear: both;
display: block;
height: 0;
visibility: hidden;
}

h1, h2, h3,
h4, h5, h6 {
color: #000;
margin-bottom: 0;
padding-bottom: 0;
}

h1 {
font-size: 2em;
}

h2 {
font-size: 1.75em;
}

h3 {
font-size: 1.2em;
}

h4 {
font-size: 1.1em;
}

h5, h6 {
font-size: 1em;
}

h5 a:link, h5 a:visited, h5 a:active {
padding: 0;
text-decoration: none;
}


/* main layout
----------------------------------------------------------*/
.content-wrapper {
margin: 0 auto;
max-width: 960px;
}

#body {
background-color: #efeeef;
clear: both;
padding-bottom: 35px;
}

.main-content {
background: url("../Images/accent.png") no-repeat;
padding-left: 10px;
padding-top: 30px;
}

.featured + .main-content {
background: url("../Images/heroAccent.png") no-repeat;
}

header .content-wrapper {
padding-top: 20px;
}

footer {
clear: both;
background-color: #e2e2e2;
font-size: .8em;
height: 100px;
}


/* site title
----------------------------------------------------------*/
.site-title {
color: #c8c8c8;
font-family: Rockwell, Consolas, "Courier New", Courier, monospace;
font-size: 2.3em;
margin: 0;
}

.site-title a, .site-title a:hover, .site-title a:active {
background: none;
color: #c8c8c8;
outline: none;
text-decoration: none;
}


/* login
----------------------------------------------------------*/
#login {
display: block;
font-size: .85em;
margin: 0 0 10px;
text-align: right;
}

#login a {
background-color: #d3dce0;
margin-left: 10px;
margin-right: 3px;
padding: 2px 3px;
text-decoration: none;
}

#login a.username {
background: none;
margin: 0;
padding: 0;
text-decoration: underline;
}

#login ul {
margin: 0;
}

#login li {
display: inline;
list-style: none;
}


/* menu
----------------------------------------------------------*/
ul#menu {
font-size: 1.3em;
font-weight: 600;
margin: 0 0 5px;
padding: 0;
text-align: right;
}

ul#menu li {
display: inline;
list-style: none;
padding-left: 15px;
}

ul#menu li a {
background: none;
color: #999;
text-decoration: none;
}

ul#menu li a:hover {
color: #333;
text-decoration: none;
}


/* page elements
----------------------------------------------------------*/
/* featured */
.featured {
background-color: #fff;
}

.featured .content-wrapper {
background-color: #7ac0da;
background-image: -ms-linear-gradient(left, #7ac0da 0%, #a4d4e6 100%);
background-image: -o-linear-gradient(left, #7ac0da 0%, #a4d4e6 100%);
background-image: -webkit-gradient(linear, left top, right top, color-stop(0, #7ac0da), color-stop(1, #a4d4e6));
background-image: -webkit-linear-gradient(left, #7ac0da 0%, #a4d4e6 100%);
background-image: linear-gradient(left, #7ac0da 0%, #a4d4e6 100%);
color: #3e5667;
padding: 20px 40px 30px 40px;
}

.featured hgroup.title h1, .featured hgroup.title h2 {
color: #fff;
}

.featured p {
font-size: 1.1em;
}

/* page titles */
hgroup.title {
margin-bottom: 10px;
}

hgroup.title h1, hgroup.title h2 {
display: inline;
}

hgroup.title h2 {
font-weight: normal;
margin-left: 3px;
}

/* features */
section.feature {
width: 300px;
float: left;
padding: 10px;
}

/* ordered list */
ol.round {
list-style-type: none;
padding-left: 0;
}

ol.round li {
margin: 25px 0;
padding-left: 45px;
}

ol.round li.zero {
background: url("../Images/orderedList0.png") no-repeat;
}

ol.round li.one {
background: url("../Images/orderedList1.png") no-repeat;
}

ol.round li.two {
background: url("../Images/orderedList2.png") no-repeat;
}

ol.round li.three {
background: url("../Images/orderedList3.png") no-repeat;
}

ol.round li.four {
background: url("../Images/orderedList4.png") no-repeat;
}

ol.round li.five {
background: url("../Images/orderedList5.png") no-repeat;
}

ol.round li.six {
background: url("../Images/orderedList6.png") no-repeat;
}

ol.round li.seven {
background: url("../Images/orderedList7.png") no-repeat;
}

ol.round li.eight {
background: url("../Images/orderedList8.png") no-repeat;
}

ol.round li.nine {
background: url("../Images/orderedList9.png") no-repeat;
}

/* content */
article {
float: left;
width: 70%;
}

aside {
float: right;
width: 25%;
}

aside ul {
list-style: none;
padding: 0;
}

aside ul li {
background: url("../Images/bullet.png") no-repeat 0 50%;
padding: 2px 0 2px 20px;
}

.label {
font-weight: 700;
}

/* login page */
#loginForm {
border-right: solid 2px #c8c8c8;
float: left;
width: 55%;
}

#loginForm .validation-error {
display: block;
margin-left: 15px;
}

#loginForm .validation-summary-errors ul {
margin: 0;
padding: 0;
}

#loginForm .validation-summary-errors li {
display: inline;
list-style: none;
margin: 0;
}

#loginForm input {
width: 250px;
}

#loginForm input[type="checkbox"],
#loginForm input[type="submit"],
#loginForm input[type="button"],
#loginForm button {
width: auto;
}

#socialLoginForm {
margin-left: 40px;
float: left;
width: 40%;
}

#socialLoginForm h2 {
margin-bottom: 5px;
}

#socialLoginList button {
margin-bottom: 12px;
}

#logoutForm {
display: inline;
}

/* contact */
.contact h3 {
font-size: 1.2em;
}

.contact p {
margin: 5px 0 0 10px;
}

.contact iframe {
border: 1px solid #333;
margin: 5px 0 0 10px;
}

/* forms */
fieldset {
border: none;
margin: 0;
padding: 0;
}

fieldset legend {
display: none;
}

fieldset ol {
padding: 0;
list-style: none;
}

fieldset ol li {
padding-bottom: 5px;
}

label {
display: block;
font-size: 1.2em;
font-weight: 600;
}

label.checkbox {
display: inline;
}

input, textarea {
border: 1px solid #e2e2e2;
background: #fff;
color: #333;
font-size: 1.2em;
margin: 5px 0 6px 0;
padding: 5px;
width: 300px;
}

textarea {
font-family: inherit;
width: 500px;
}

input:focus, textarea:focus {
border: 1px solid #7ac0da;
}

input[type="checkbox"] {
background: transparent;
border: inherit;
width: auto;
}

input[type="submit"],
input[type="button"],
button {
background-color: #d3dce0;
border: 1px solid #787878;
cursor: pointer;
font-size: 1.2em;
font-weight: 600;
padding: 7px;
margin-right: 8px;
width: auto;
}

td input[type="submit"],
td input[type="button"],
td button {
font-size: 1em;
padding: 4px;
margin-right: 4px;
}

/* info and errors */
.message-info {
border: 1px solid;
clear: both;
padding: 10px 20px;
}

.message-error {
clear: both;
color: #e80c4d;
font-size: 1.1em;
font-weight: bold;
margin: 20px 0 10px 0;
}

.message-success {
color: #7ac0da;
font-size: 1.3em;
font-weight: bold;
margin: 20px 0 10px 0;
}

.error {
color: #e80c4d;
}

/* styles for validation helpers */
.field-validation-error {
color: #e80c4d;
font-weight: bold;
}

.field-validation-valid {
display: none;
}

input.input-validation-error {
border: 1px solid #e80c4d;
}

input[type="checkbox"].input-validation-error {
border: 0 none;
}

.validation-summary-errors {
color: #e80c4d;
font-weight: bold;
font-size: 1.1em;
}

.validation-summary-valid {
display: none;
}


/* tables
----------------------------------------------------------*/
table {
border-collapse: collapse;
border-spacing: 0;
margin-top: 0.75em;
border: 0 none;
}

th {
font-size: 1.2em;
text-align: left;
border: none 0px;
padding-left: 0;
}

th a {
display: block;
position: relative;
}

th a:link, th a:visited, th a:active, th a:hover {
color: #333;
font-weight: 600;
text-decoration: none;
padding: 0;
}

th a:hover {
color: #000;
}

th.asc a, th.desc a {
margin-right: .75em;
}

th.asc a:after, th.desc a:after {
display: block;
position: absolute;
right: 0em;
top: 0;
font-size: 0.75em;
}

th.asc a:after {
content: '▲';
}

th.desc a:after {
content: '▼';
}

td {
padding: 0.25em 2em 0.25em 0em;
border: 0 none;
}

tr.pager td {
padding: 0 0.25em 0 0;
}


/********************
* Mobile Styles *
********************/
@media only screen and (max-width: 850px) {

/* header
----------------------------------------------------------*/
header .float-left,
header .float-right {
float: none;
}

/* logo */
header .site-title {
margin: 10px;
text-align: center;
}

/* login */
#login {
font-size: .85em;
margin: 0 0 12px;
text-align: center;
}

#login ul {
margin: 5px 0;
padding: 0;
}

#login li {
display: inline;
list-style: none;
margin: 0;
padding: 0;
}

#login a {
background: none;
color: #999;
font-weight: 600;
margin: 2px;
padding: 0;
}

#login a:hover {
color: #333;
}

/* menu */
nav {
margin-bottom: 5px;
}

ul#menu {
margin: 0;
padding: 0;
text-align: center;
}

ul#menu li {
margin: 0;
padding: 0;
}


/* main layout
----------------------------------------------------------*/
.main-content,
.featured + .main-content {
background-position: 10px 0;
}

.content-wrapper {
padding-right: 10px;
padding-left: 10px;
}

.featured .content-wrapper {
padding: 10px;
}

/* page content */
article, aside {
float: none;
width: 100%;
}

/* ordered list */
ol.round {
list-style-type: none;
padding-left: 0;
}

ol.round li {
padding-left: 10px;
margin: 25px 0;
}

ol.round li.zero,
ol.round li.one,
ol.round li.two,
ol.round li.three,
ol.round li.four,
ol.round li.five,
ol.round li.six,
ol.round li.seven,
ol.round li.eight,
ol.round li.nine {
background: none;
}

/* features */
section.feature {
float: none;
padding: 10px;
width: auto;
}

section.feature img {
color: #999;
content: attr(alt);
font-size: 1.5em;
font-weight: 600;
}

/* forms */
input {
width: 90%;
}

/* login page */
#loginForm {
border-right: none;
float: none;
width: auto;
}

#loginForm .validation-error {
display: block;
margin-left: 15px;
}

#socialLoginForm {
margin-left: 0;
float: none;
width: auto;
}


/* footer
----------------------------------------------------------*/
footer .float-left,
footer .float-right {
float: none;
}

footer {
text-align: center;
height: auto;
padding: 10px 0;
}

footer p {
margin: 0;
}
}



درنهایت پروژه را اجرا کنید

موفق باشید

bitcob589
یک شنبه 30 شهریور 1393, 17:04 عصر
چگونه می توان زیر منوهای که زیر منو دارند علامت فلش در جلوی آنها بگذاریم تا مشخص این زیر منو دارای زیر منو می باشد.(نحوه گذاشتن علامت فلش جلوی زیر منوهای که دارای زیر منو هستند مثل عکس)
123743

raha raad
سه شنبه 17 بهمن 1396, 12:56 عصر
عالیه. دستتون درد نکنه. :تشویق:
من هنوز کدها رو بررسی و استفاده نکردم.
ولی سوال برام پیش اومده که این کدی که زحمتش رو کشیدید تا چند سطح زیر منو می گیره؟؟؟؟
همینطور اگه لطف کنید و کد ایجاد مگامنوی داینامیک رو هم قرار بدید بینهایت ممنونتون میشم.

بازم تشکر می کنم بابت مطلب مفیدتون. :لبخندساده:

mta007
سه شنبه 22 بهمن 1398, 14:26 عصر
سلام ببخشید برای من زیر منو ها نمیاد چرا