من نیاز دارم تا در Page Header و Group Header از قالب تهیه شده توسط Open Office استفاده کنم. قالب هایی که تهیه شدن، یه سری فیلد دارن که موقع ساخت گزارش باید پر بشن.
چطور باید فیلدهای موجود در قالب رو بعد از لود مقدار دهی کرد؟
%GIT_HOME%\cmd;C:\Program Files (x86)\nodejs\;%JAVA_HOME%\bin;%ANT_HOME%\bin; %ANDROID_HOME%\tools;%ANDROID_HOME%\platform-tools; C:\ProgramData\Oracle\Java\javapath;
تصویر فوق مربوط به لینک یک سایت خبری در ادیتور فیسبوک میباشد. همانطور که میبینید عنوان خبر، عکس و توضیح مختصری در مورد خبر، با نظم و ترتیبی خاص نمایش داده شده است.
حال به تصویر زیر که مربوط به لینکی از همین سایت میباشد دقت کنید:
<html itemscope itemtype="http://schema.org/Article">
<title>عنوان صفحه ، حداکثر 60 تا 70 کارکتر باشد</title> <meta name="description" content="شرح صفحه ، حداکثر 150 کارکتر باشد" /> <!-- Schema.org markup for Google+ --> <meta itemprop="name" content="نام یا عنوان صفحه"> <meta itemprop="description" content="شرح صفحه"> <meta itemprop="image" content="نشانی اینترنتی عکسی که در پیشنمایش نشان داده میشود"> <!-- Twitter Card data --> <meta name="twitter:card" content="summary_large_image"> <meta name="twitter:site" content="کپی رایت نام سایت"> <meta name="twitter:title" content="نام یا عنوان صفحه"> <meta name="twitter:description" content="شرح صفحه"> <meta name="twitter:creator" content="نویسنده"> <!-- Picture size at least 280x150px -->عکس پیشنمایش با ابعاد حداقل <meta name="twitter:image:src" content="نشانی اینترنتی عکس مطلب"> <!-- Open Graph data --> <meta property="og:title" content="عنوان صفحه" /> <meta property="og:type" content="article" /> <meta property="og:url" content="نشانی سایت" /> <meta property="og:image" content="نشانی عکس مطلب" /> <meta property="og:description" content="شرح مطلب" /> <meta property="og:site_name" content="نام سایت" /> <meta property="article:published_time" content="تاریخ انتشار" /> <meta property="article:modified_time" content="تاریخ بروزرسانی" /> <meta property="article:section" content="نام بخش محتوی متن مقاله" /> <meta property="article:tag" content="نام تگ محتوی متن مقاله" /> <meta property="fb:admins" content="شناسه عددی کاربری شما در فیسبوک" />
<html itemscope itemtype="http://schema.org/Product">
<title>عنوان صفحه</title> <meta name="description" content="شرح صفحه" /> <!-- Schema.org markup for Google+ --> <meta itemprop="name" content="عنوان صفحه"> <meta itemprop="description" content="Tشرح صفحه"> <meta itemprop="image" content="نشانی عکس محصول یا کالا"> <!-- Twitter Card data --> <meta name="twitter:card" content="product"> <meta name="twitter:site" content="کپی رایت سایت"> <meta name="twitter:title" content="عنوان صفحه"> <meta name="twitter:description" content="شرح محصول یا کالا"> <meta name="twitter:creator" content="نویسنده"> <meta name="twitter:image" content="نشانی عکس محصول یا کالا"> <meta name="twitter:data1" content="قیمت محصول یا کالا"> <meta name="twitter:label1" content="Price"> <meta name="twitter:data2" content="رنگ کالا یا محصحول"> <meta name="twitter:label2" content="Color"> <!-- Open Graph data --> <meta property="og:title" content="عنوان صفحه" /> <meta property="og:type" content="article" /> <meta property="og:url" content="نشانی سایت" /> <meta property="og:image" content="عکس محصول یا کالا" /> <meta property="og:description" content="شرح مصحول" /> <meta property="og:site_name" content="نام سایت" /> <meta property="og:price:amount" content="قیمت محصول یا کالا" /> <meta property="og:price:currency" content="واحد ارزی قیمت" />
public static void PrintNumbers() { var numbers = new[] { 1,2,3,5,7,90 }; // from a data source foreach(var item in numbers) { Console.WriteLine(item); } }
public static void PrintNumbers(Func<int,string> formula) { var numbers = new[] { 1,2,3,5,7,90 }; // from a data source foreach(var item in numbers) { var data = formula(item); Console.WriteLine(data); } }
PrintNumbers(number => string.Format("{0:n0}",number));
PrintNumbers((number) =>{ return string.Format("{0:n0}",number); });
using System; using System.Web; using System.Web.Caching; using System.Collections.Generic; namespace WebToolkit { public static class CacheManager { public static void CacheInsert(this HttpContextBase httpContext, string key, object data, int durationMinutes) { if (data == null) return; httpContext.Cache.Add( key, data, null, DateTime.Now.AddMinutes(durationMinutes), TimeSpan.Zero, CacheItemPriority.AboveNormal, null); } } }
var item = httpContext.Cache[key]; if (item == null) { item = ReadDataFromDataSource(); if (item == null) return null; CacheInsert(httpContext, key, item, durationMinutes); }
using System; using System.Web; using System.Web.Caching; using System.Collections.Generic; namespace WebToolkit { public static class CacheManager { public static void CacheInsert(this HttpContextBase httpContext, string key, object data, int durationMinutes) { if (data == null) return; httpContext.Cache.Add( key, data, null, DateTime.Now.AddMinutes(durationMinutes), TimeSpan.Zero, CacheItemPriority.AboveNormal, null); } public static T CacheRead<T>(this HttpContextBase httpContext, string key, int durationMinutes, Func<T> ifNullRetrievalMethod) { var item = httpContext.Cache[key]; if (item == null) { item = ifNullRetrievalMethod(); if (item == null) return default(T); CacheInsert(httpContext, key, item, durationMinutes); } return (T)item; } } }
var user = HttpContext.CacheRead( "Key1", 15, () => _usersService.FindUser(userId));
StiImage stiImg = new StiImage(); stiImg.Image = img;
Column Store Index یکی از ویژگیهای جدید SQL Server 2012 می باشد، که کارایی Query های قایل اجرا روی دیتابیسهای با حجم داده ای بسیار بالا را (که اصطلاحا به آنها Data Warehouse یا انبار داده گویند)، چندین برابر بهبود بخشیده است.
قبل از توضیح در مورد Column Store مختصری در مورد نحوه ذخیره سازی دادهها در SQL Server می پردازیم. میتوان گفت در SQL Server دو روش ذخیره سازی وجود دارد،یکی بصورت ردیفی که اصطلاحا به آن Row Storeیا Row-Wise گویند، و دیگری بصورت ستونی که اصطلاحا به آن Column Store گویند.
در روش ذخیره سازی Row Store، مقادیر ستونها در یک سطر بصورت متوالی ذخیره میشوند، در این روش ذخیره سازی از ساختار B-Tree یا Heap استفاده میشود.
یادآوری: در ساختار B-Tree، یک گره Root وجود دارد، و گره بعد از Root گره ای است که آدرس گره راست بعدی و آدرس گره چپ بعدی را در خود نگه میدارد.
شکل زیر نمای یک درخت B-Tree میباشد:
جهت کسب اطلاعات بیشتر درمورد ساختار B-Tree
یادآوری: وقتی در یک جدول، ایندکسی از نوع Clustered ایجاد نماییم، SQL Server، در ابتدا یک کپی از جدول ایجاد و دادههای جدول را از نو مرتب مینماید، و ساختار صفحه ریشه و دیگر صفحات را ایجاد میکند و سپس جدول اصلی را حذف مینماید. به جدولی که Clustered Index ندارد، اصطلاحا Heap گویند.
برخلاف ذخیره سازی Row Store، در ذخیره سازی Column Store، دادهها بصورت ستونی ذخیره میشوند،در این روش داده ها، فشرده سازی میشوند و اینکار باعث میشود،در زمان درخواست یک Query، نیاز به Disk I/o به حداقل برسد، در نتیجه، زمان و سرعت پاسخگویی به پرس و جوها بسیار افزایش مییابد.
شکل زیر نحوه ذخیره سازی داده ها،بصورت Row Store را نمایش میدهد:
شکل بالا ذخیره سازی داده ها، در ساختار B-Tree یا Heap را نمایش میدهد، در شکل فوق یک جدول چهار ستونی با N سطر (Row) در نظر گرفته شده است.بطوریکه ستونهای هر Row بطور متوالی در یک صفحه (Page) یکسان ذخیره میشوند.
شکل زیر نحوه ذخیره سازی داده ها،بصورت Column Store را نمایش میدهد:
مطابق شکل،ستونهای مربوط به هر Row،همگی در یک صفحه (Page) یکسان ذخیره شده اند. به عنوان مثال ستون C1 که مربوط به سطر اول (Row1) میباشد، با ستون C1 که مربوط به سطر دوم (Row2) میباشد، در یک ستون و در یک صفحه (Page1) ذخیره شده اند، و الی آخر ...
سئوال: یکبار دیگر به هردو شکل با دقت نگاهی بیاندازید، عمده تفاوت آنها در چیست؟
جواب: درست حدس زدید، تفاوت بارز بین دو روش Column Store و Row Store در نحوه ذخیره سازی دادهها میباشد. بطور مثال، فرض کنید،در روش ذخیره سازی Row Store، به دنبال مقادیری از ستون C2 میباشید، SQL Server میبایست کل رکوردهای جدول (منظور همه Rowها در همه Page ها)را Scan نماید، تا مقادیر مربوط به ستون C2 را بدست آورد.درحالیکه در روش ذخیره سازی Column Store، جهت یافتن مقادیر ستون C2، نیازی به Scan نمودن کل جدول نیست،بلکه SQL Server فقط به Scan نمودن ستون دوم (C2) یا Page2 بسنده مینماید.همین امر باعث افزایش چندین برابری، زمان پاسخگویی به هر Query میشود.
سئوال: در روش ذخیره سازی Column Store، چگونه مصرف حافظه بهینه میشود؟
جواب: واضح است، که در روش SQL Server، Row Store مجبور است، برای بدست آوردن دادههای مورد نظرتان،کل اطلاعات جدول را وارد حافظه نماید(اطلاعات اضافه ای که به هیچ وجه بدرد، نتیجه پرس و جوی شما نمیخورد)، و شروع به Scan دادههای مد نظر شما مینماید.بطوریکه در روش SQL Server، Column Store، فقط ستون دادههای مورد پرس و جو را در حافظه قرار میدهد.(در واقع فقط داده هایی را در حافظه قرار میدهد، که شما به آن نیاز دارید)،بنابراین،طبیعی است که در روش Column Store مقدار حافظه کمتری نسبت به روش Row Store در هنگام اجرای Query استفاده میشود. به عبارت دیگر میتوان گفت که در روش Column Store به دلیل، به حداقل رساندن استفاده از Disk I/o سرعت و زمان پاسخگویی به پرس و جوها چندین برابر میشود.
برای درک بیشتر Row Store و Column Store مثالی میزنیم:
فرض کنید،قصد بدست آوردن ستونهای C1 و C2 از جدول A را داریم، بنابراین خواهیم داشت:
Select C1, C2 from A
روش Row Store:
در این روش همه صفحات دیسک (مربوط به جدول A) درون حافظه قرار داده میشود، یعنی علاوه بر ستونهای C1 و C2، اطلاعات مربوط به ستونهای C3 و C4 نیز درون حافظه قرار میگیرد،بطوریکه مقادیر ستونهای C3 و C4 به هیچ وجه مورد قبول ما نیست، و در خروجی پرس و جوی ما تاثیری ندارد، و فقط بی جهت حافظه اشغال مینماید.
روش Column Store:
در این روش فقط صفحات مروبط به ستون C1 و C2 در حافظه قرار میگیرد.(منظور Page1 و Page2 میباشد) بنابراین فقط اطلاعات مورد نیاز در خروجی، در حافظه قرار میگیرد.
چه موقع میتوانیم از Column Store استفاده نماییم:
در تعریف Column Store گفته بودم، روش فوق، جهت بهبود بخشیدن به زمان و سرعت پاسخگویی به Queryهای اجرا شده روی دیتابیسهای با حجم داده ای بسیار بالا(Data Warehouse ) میباشد، به بیان سادهتر Column Store را روی دیتابیسهای offline یا دیتابیسهایی که صرفا جهت گزارش گیری مورد استفاده قرار میگیرند، تنظیم مینمایند.در واقع با تنظیم Column Store Index روی Databaseهای بزرگ مانند Databaseهای بانکها که حجم داده ای میلیونی در جداول آنها وجود دارد، سرعت پاسخگویی Query ها، چندین برابر افزایش مییابد.
CREATE [ NONCLUSTERED ] COLUMNSTORE INDEX index_name ON <object> ( column [ ,...n ] ) [ WITH ( <column_index_option> [ ,...n ] ) ] [ ON { { partition_scheme_name ( column_name ) } | filegroup_name | "default" } ] [ ; ] <object> ::= { [database_name. [schema_name ] . | schema_name . ] table_name { <column_index_option> ::= { DROP_EXISTING = { ON | OFF } | MAXDOP = max_degree_of_parallelism }
CREATE NONCLUSTERED COLUMNSTORE INDEX [IX_MyFirstName_ColumnStore] ON [Test] (Firstname)
ALTER INDEX [IX_MyFirstName_ColumnStore] ON [Test] DISABLE ALTER INDEX [IX_MyFirstName_ColumnStore] ON [Test] Rebuild
[HttpGet("[action]")] public async Task<IActionResult> UsersList() { var users = await _dbContext.Users.AsNoTracking().ToListAsync(); return Ok(users); }
[HttpGet("[action]")] public async Task<IActionResult> UsersList(GridifyQuery filter) { var users = await _dbContext.Users.AsNoTracking().GridifyAsync(filter); return Ok(users); }
var result = Users.AsQueryable().ApplyFiltering("name==Ali");
var result = Users.AsQueryable().Where(q => q.Name == "Ali");
پی نوشت: برای داشتن نیوگت شخصی سایتهای نظیر Nuget Server و Myget ( به همراه پشتیبانی از مخازن npm و Bower ) هم این سرویس را ارائه میکنند. ولی باید هزینهی آن را پرداخت کنید. البته سایت GemFury مخازن رایگان مختلفی چون Nuget را نیز پشتیبانی میکند.
nuget init e:\nuget\ e:\nuget\test
nuget add GMap.Net.1.0.1.nupkg -source e:\nuget\test
Install-Package NuGet.Server
<appSettings> <!-- Set the value here to specify your custom packages folder. --> <add key="packagesPath" value="×\Packages" /> </appSettings>
(هر محلی که نصب کنید طبق الگوی مسیریابی، آدرس nuget را در انتها وارد کنید)
Dotnettips.info/nuget
nuget push GMap.Net.1.0.1.nupkg -source http://Dotenettips.info/nuget (ApiKey)
nuget setapikey -source https://www.dntips.ir/Nuget (ApiKey)
<Window x:Class="FirstPrismSample.Shell" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:com="http://www.codeplex.com/CompositeWPF" Title="Prism Sample By Masoud Pakdel" Height="400" Width="600" WindowStartupLocation="CenterScreen"> <DockPanel> <ContentControl com:RegionManager.RegionName="WorkspaceRegion" Width="400"/> <ContentControl com:RegionManager.RegionName="NavigatorRegion" DockPanel.Dock="Left" Width="200" /> </DockPanel> </Window>
کد کلاس ViewModelBase که فقط اینترفیس INotifyPropertyChanged رو پیاده سازی کرده است:
using System.ComponentModel; namespace FirstPrismSample.Common { public abstract class ViewModelBase : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; protected void RaisePropertyChangedEvent( string propertyName ) { if ( PropertyChanged != null ) { PropertyChangedEventArgs e = new PropertyChangedEventArgs( propertyName ); PropertyChanged( this, e ); } } } }
using Microsoft.Practices.Composite.Presentation.Events; namespace FirstPrismSample.Common.Events { public class ViewRequestedEvent : CompositePresentationEvent<string> { } }
namespace FirstPrismSample .Common { public interface IModuleServices { void ActivateView(string viewName); } }
using Microsoft.Practices.Composite.Regions; using Microsoft.Practices.Unity; namespace FirstPrismSample.Common { public class ModuleServices : IModuleServices { private readonly IUnityContainer m_Container; public ModuleServices(IUnityContainer container) { m_Container = container; } public void ActivateView(string viewName) { var regionManager = m_Container.Resolve<IRegionManager>(); // غیر فعال کردن ویو IRegion workspaceRegion = regionManager.Regions["WorkspaceRegion"]; var views = workspaceRegion.Views; foreach (var view in views) { workspaceRegion.Deactivate(view); } //فعال کردن ویو انتخاب شده var viewToActivate = regionManager.Regions["WorkspaceRegion"].GetView(viewName); regionManager.Regions["WorkspaceRegion"].Activate(viewToActivate); } } }
<UserControl x:Class="FirstPrismSample.ModuleCategory.CategoryView " xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Background="LightGray" FlowDirection="RightToLeft" FontFamily="Tahoma"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <TextBlock Text=" طبقه بندی ها"/> <ListView Grid.Row="1" Margin="10" Name="lvCategory"> <ListView.View> <GridView> <GridViewColumn Header="کد" Width="50" /> <GridViewColumn Header="عنوان" Width="200" /> </GridView> </ListView.View> </ListView> </Grid> </UserControl>
using Microsoft.Practices.Composite.Events; using Microsoft.Practices.Composite.Modularity; using Microsoft.Practices.Composite.Regions; using Microsoft.Practices.Unity; using FirstPrismSample.Common; using FirstPrismSample.Common.Events; using Microsoft.Practices.Composite.Presentation.Events; namespace FirstPrismSample.ModuleCategory { [Module(ModuleName = "ModuleCategory")] public class CategoryModule : IModule { private readonly IUnityContainer m_Container; private readonly string moduleName = "ModuleCategory"; public CategoryModule(IUnityContainer container) { m_Container = container; } ~CategoryModule() { var eventAggregator = m_Container.Resolve<IEventAggregator>(); var viewRequestedEvent = eventAggregator.GetEvent<ViewRequestedEvent>(); viewRequestedEvent.Unsubscribe(ViewRequestedEventHandler); } public void Initialize() { var regionManager = m_Container.Resolve<IRegionManager>(); regionManager.Regions["WorkspaceRegion"].Add(new CategoryView(), moduleName); var eventAggregator = m_Container.Resolve<IEventAggregator>(); var viewRequestedEvent = eventAggregator.GetEvent<ViewRequestedEvent>(); viewRequestedEvent.Subscribe(this.ViewRequestedEventHandler, true); } public void ViewRequestedEventHandler(string moduleName) { if (this.moduleName != moduleName) return; var moduleServices = m_Container.Resolve<IModuleServices>(); moduleServices.ActivateView(moduleName); } } }
*برای تعریف ماژول کلاس مورد نظر حتما باید اینترفیس IModule را پیاده سازی کند. این اینترفیس فقط شامل یک متد است به نام Initialize.
*در این پروژه چون Viewهای برنامه صرفا جهت نمایش هستند در نتیجه نیاز به ایجاد ViewModel برای آنها نیست. در پروژههای اجرایی حتما برای هر View باید ViewModel متناظر با آن تهیه شود.
توضیح درباره متد Initialize
در این متد ابتدا با استفاده از Container موجود RegionManager را به دست میآوریم. با استفاده از RegionManager میتونیم یک CompositeUI طراحی کنیم. در فایل Shell مشاهده کردید که یک صفحه به دو ناحیه تقسیم شد و به هر ناحیه هم یک نام اختصاص دادیم. دستور زیر به یک ناحیه اشاره خواهد داشت:
regionManager.Regions["WorkspaceRegion"]
<UserControl x:Class="FirstPrismSample.ModuleBook.BookView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Background="LightGray" FontFamily="Tahoma" FlowDirection="RightToLeft"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <TextBlock Text="لیست کتاب ها"/> <ListView Grid.Row="1" Margin="10" Name="lvBook"> <ListView.View> <GridView> <GridViewColumn Header="کد" Width="50" /> <GridViewColumn Header="عنوان" Width="200" /> <GridViewColumn Header="نویسنده" Width="150" /> </GridView> </ListView.View> </ListView> </Grid> </UserControl>
using Microsoft.Practices.Composite.Events; using Microsoft.Practices.Composite.Modularity; using Microsoft.Practices.Composite.Presentation.Events; using Microsoft.Practices.Composite.Regions; using Microsoft.Practices.Unity; using FirstPrismSample.Common; using FirstPrismSample.Common.Events; namespace FirstPrismSample.ModuleBook { [Module(ModuleName = "moduleBook")] public class BookModule : IModule { private readonly IUnityContainer m_Container; private readonly string moduleName = "ModuleBook"; public BookModule(IUnityContainer container) { m_Container = container; } ~BookModule() { var eventAggregator = m_Container.Resolve<IEventAggregator>(); var viewRequestedEvent = eventAggregator.GetEvent<ViewRequestedEvent>(); viewRequestedEvent.Unsubscribe(ViewRequestedEventHandler); } public void Initialize() { var regionManager = m_Container.Resolve<IRegionManager>(); var view = new BookView(); regionManager.Regions["WorkspaceRegion"].Add(view, moduleName); regionManager.Regions["WorkspaceRegion"].Deactivate(view); var eventAggregator = m_Container.Resolve<IEventAggregator>(); var viewRequestedEvent = eventAggregator.GetEvent<ViewRequestedEvent>(); viewRequestedEvent.Subscribe(this.ViewRequestedEventHandler, true); } public void ViewRequestedEventHandler(string moduleName) { if (this.moduleName != moduleName) return; var moduleServices = m_Container.Resolve<IModuleServices>(); moduleServices.ActivateView(m_WorkspaceBName); } } }
<UserControl x:Class="FirstPrismSample.ModuleNavigator.NavigatorView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <Grid> <StackPanel VerticalAlignment="Center"> <TextBlock Text="انتخاب ماژول" Foreground="Green" HorizontalAlignment="Center" VerticalAlignment="Center" FontFamily="Tahoma" FontSize="24" FontWeight="Bold" /> <Button Command="{Binding ShowModuleCategory}" Margin="5" Width="125">طبقه بندی کتاب ها</Button> <Button Command="{Binding ShowModuleBook}" Margin="5" Width="125">لیست کتاب ها</Button> </StackPanel> </Grid> </UserControl>
public interface INavigatorViewModel { ICommand ShowModuleCategory { get; set; } ICommand ShowModuleBook { get; set; } string ActiveWorkspace { get; set; } IUnityContainer Container { get; set; } event PropertyChangedEventHandler PropertyChanged; }
public class NavigatorViewModel : ViewModelBase, INavigatorViewModel { public NavigatorViewModel(IUnityContainer container) { this.Initialize(container); } public ICommand ShowModuleCategory { get; set; } public ICommand ShowModuleBook { get; set; } public string ActiveWorkspace { get; set; } public IUnityContainer Container { get; set; } private void Initialize(IUnityContainer container) { this.Container = container; this.ShowModuleCategory = new ShowModuleCategoryCommand(this); this.ShowModuleBook = new ShowModuleBookCommand(this); this.ActiveWorkspace = "ModuleCategory"; } }
public class ShowModuleCategoryCommand : ICommand { private readonly NavigatorViewModel viewModel; private const string workspaceName = "ModuleCategory"; public ShowModuleCategoryCommand(NavigatorViewModel viewModel) { this.viewModel = viewModel; } public bool CanExecute(object parameter) { return viewModel.ActiveWorkspace != workspaceName; } public event EventHandler CanExecuteChanged { add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; } } public void Execute(object parameter) { CommandServices.ShowWorkspace(workspaceName, viewModel); } }
public class ShowModuleBookCommand : ICommand { private readonly NavigatorViewModel viewModel; private readonly string workspaceName = "ModuleBook"; public ShowModuleBookCommand( NavigatorViewModel viewModel ) { this.viewModel = viewModel; } public bool CanExecute( object parameter ) { return viewModel.ActiveWorkspace != workspaceName; } public event EventHandler CanExecuteChanged { add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; } } public void Execute( object parameter ) { CommandServices.ShowWorkspace( workspaceName , viewModel ); } }
public static void ShowWorkspace(string workspaceName, INavigatorViewModel viewModel) { var eventAggregator = viewModel.Container.Resolve<IEventAggregator>(); var viewRequestedEvent = eventAggregator.GetEvent<ViewRequestedEvent>(); viewRequestedEvent.Publish(workspaceName); viewModel.ActiveWorkspace = workspaceName; }
xcopy "$(TargetDir)FirstPrismSample.ModuleBook.dll" "$(SolutionDir)FirstPrismSample\bin\$(ConfigurationName)\Modules\" /Y
public class Bootstrapper : UnityBootstrapper { protected override void ConfigureContainer() { base.ConfigureContainer(); Container.RegisterType<IModuleServices, ModuleServices>(); } protected override DependencyObject CreateShell() { var shell = new Shell(); shell.Show(); return shell; } protected override IModuleCatalog GetModuleCatalog() { var catalog = new DirectoryModuleCatalog(); catalog.ModulePath = @".\Modules"; return catalog; } }
"$(SolutionDir)FirstPrismSample\bin\$(ConfigurationName)\Modules\" /Y
public partial class App : Application { protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); var bootstrapper = new Bootstrapper(); bootstrapper.Run(); } }
Panel Toolbar
ابزاری موجود در این پنل مشابه پنلهای دیگر در بالای پنل و در زیر تب پنلها قرار دارد و شامل ابزارهای زیر میشود:
Panel
منظور از پنل ، قسمتی هست که استایل بصورت فرمت شده و نمایش داده شده است.
Infotips
توسط این قابلیت ، زمانی که موس را بروی آدرس تصاویر ، نوع فونت و ... ببرید ، پاپ آپ کوچکی باز میشود و اطلاعاتی در مورد مقادیر میدهد. مثلا اینکه آیا تصویر مورد نظر به درستی بارگذاری شده یا نه ، نمای کوچکی از تصویر ، شکل فونت و ...
Editing rules
برای ویرایش تعاریف CSS شامل Selectorها ، دستورات و مقادیر ، این پنل ابزارهای مفیدی ارائه میکند.
برای ویرایش یک selector ، دستور یا مقدار آن بروی آن عبارت کلیک کنید ، در همین حال یک text box ظاهر میشود و میتوانید مقدار جدید را وارد کنید. پس از انجام ویرایش مورد نظر بروی قسمتی از صفحه کلیک کنید یا کلید Tab سپس Esc را بزنید. برای ویرایش دستورات بعدی ، کلید Tab را بزنید و برای لغو تغییر جاری ، کلید Esc را بزنید.
برای ایجاد یک rule جدید ، بروی قسمتی از پنل راست کلیک کرده و سپس گزینهی "New Rule..." را برگزینید.
برای ایجاد یک property هم چند راه وجود دارد:
هنگام ویرایش یا ایجاد یک Rule , Propery یا مقدار بصورت inline ، حاشیهی text box متناسب با مقدار وارد شده رنگی را که نمایانگر حالت ذخیرهی مقدار وارد شده است نمایش میدهد. برای مثال اگر مقداری که برای یک selector وارد شده است نامعتبر باشد ، رنگ حاشیهی text box قرمز میشود.
جدول زیر حالتهای مختلف را شرح میدهد:
رنگ حاشیه | Selectorها | نام Properyها | مقادیر Propertyها و Ruleها |
خاکستری | تغییری ایجاد نشده است | تغییری ایجاد نشده است | تغییری ایجاد نشده است |
قرمز | selector نامعتبر است | نام نامعتبر است | مقدار نامعتبر است |
زرد | selector صحیح است اما بروی Element فعلی تاثیر ندارد | نام صحیح است اما مقدار Property غیر مجاز است یا وارد نشده است | |
سبز | selector صحیح است | نام و مقدار صحیح هستند | مقدار صحیح است |
Auto-completion
زمانی که در حال ایجاد/ویراش کردن یک Rule, Propery یا مقدار آنها هستید ، میتوانید از این قابلیت استفاده کنید. مثلا با وارد کردن # تمام Selector هایی که میتوانند با # شروع شوند در دسترس شما هستند و با دکمههای Up/Down میتوانید مقادیر ممکن را مرور کنید.
اگر در حال ویرایش یک مقدار عددی هستید ، میتوانید با دکمههای Up/Down مقادیر را یک واحد یک واحد افزایش دهید. با نگه داشتن کلید Shift و فشردن Up/Down میتوانید مقادیر را 10تا 10تا تغییر دهید و با نگه داشتن Ctrl بجای Sihft ، یک دهم یک دهم.
Toggling styles
با این امکان میتوانید یک Property را بطور موقت فعال/غیرفعال کنید. با حرکت موس از یک Property یک آیکون قرمز رنگ در کنار آن نمایش داده میشود که با کلیک بروی آن ، Property و مقدار آن کمرنگ شده و آیکون قرمز رنگ کنار آن ثابت میشود. با کلیک مجدد بروی آن ، Property فعال میشود.
Context Menu
این منو زمانی که در پنل راست کلیک کنید ظاهر میشود و نسبت به منطقه (Context)ای که در آن راست کلیک کرده اید ، گزینههای متفاوتی را مشاهده خواهید کرد. در جدول زیر ، گزینهها ، Contextشان و توضیح هر گزینه آمده است.
گزینه | Context | توضیحات |
Copy Location | CSS Location Menu | آدرس فایل استایل را در حافظه کپی میکند. |
Open in New Tab | CSS Location Menu | فایل استایل را در یک تب جدید باز میکند. |
Copy Image Location | image values | آدرس تصویر را در حافظه کپی میکند. |
Open Image in New Tab | image values | تصویر را در یک تب جدید باز میکند. |
Copy Color | color values | مقدار رنگ را در حافظه کپی میکند. |
Copy Rule Declaration | CSS selector | Selector و Propertyها را در حافظه کپی میکند. |
Copy Style Declaration | CSS selector | فقط Propertyها را در حافظه کپی میکند. |
New Rule... | همه جای پنل | یک Rule جدید بالای قسمتی که راست کلیک شده ایجاد میکند. |
Delete "<selector>" | CSS selector | Rule را حذف میکند. |
New Property... | CSS rule | یک Property جدید در Ruleی که در آن راست کلیک شده ایجاد میکند. |
Edit "<property name>"... | CSS property | Property فعلی به حالت ویرایش درمی آید. ( راه سادهتر ، کلیک بروی Property است. ) |
Delete "<property name>"... | CSS property | Property فعلی را حذف میکند. |
Disable "<property name>"... | CSS property | Property فعلی را غیرفعال میکند. |
Refresh | همه جای پنل | محتویات پنل را بروز رسانی میکند. |
Inspect in DOM panel | CSS Location Menu, CSS rule | فایل استایل یا Rule را در پنل DOM باز میکند. |
Elements Side Panel
در این پنل که سمت راست پنل CSS قرار دارد ، با وارد کردن یک CSS Selector میتوانید Elementهایی که در صفحه با آن مطابقت دارند را مشاهده کنید.
برای وارد کردن CSS Selector هم میتوان مقدار مورد نظر را در قسمت Try a selector... وارد کرد هم میتوان بروی یکی از Selectorهای پنل راست کلیک کرد و گزینهی Get Matching Elements را برگزید.
Context Menu این قسمت هم مشابه Context Menu پنل HTML هست و فقط در ورژن 1.11 گزینهی Paste HTML اضافه شده که در این کامنت از مقالهی آموزش فایرباگ - #5 - HTML Panel توضیح داده شده است.