<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-7815821915651048578</atom:id><lastBuildDate>Thu, 26 Jan 2012 09:52:24 +0000</lastBuildDate><category>others</category><category>Unit testing</category><category>Design patterns</category><category>WCF RIA Services</category><category>MVVM</category><category>MAF</category><category>SQL Server</category><category>OpenSSL</category><category>SubtitleTools</category><category>SQLite</category><category>Security</category><category>SFDown</category><category>Regular expressions</category><category>C++</category><category>VSTO</category><category>RSS</category><category>BloggerToCHM</category><category>Debugging</category><category>Windows forms</category><category>Virtualization</category><category>News</category><category>HTML5</category><category>Windows 7</category><category>LINQ</category><category>xml</category><category>DGML</category><category>MySQL</category><category>Subversion</category><category>OpenXML</category><category>BAP</category><category>SharePoint</category><category>SQL Server CE</category><category>UML</category><category>system.net</category><category>Tips</category><category>VB</category><category>Blogger</category><category>IIS</category><category>links</category><category>Refactoring</category><category>ASM</category><category>ADO.NET</category><category>Exchange Server</category><category>C#</category><category>WinRT</category><category>Firefox</category><category>iTextSharp</category><category>NuGet</category><category>Agile</category><category>WCF</category><category>Oslo</category><category>WorkFlow Foundation</category><category>Entity framework</category><category>CHM</category><category>Scrum</category><category>NHibernate</category><category>Tools</category><category>VS</category><category>ASP.Net</category><category>JavaScript</category><category>WPF</category><category>json</category><category>Silverlight</category><title>.NET Tips</title><description /><link>http://www.dotnettips.info/</link><managingEditor>noreply@blogger.com (وحيد نصيري)</managingEditor><generator>Blogger</generator><openSearch:totalResults>782</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/vahidnasiri" /><feedburner:info uri="vahidnasiri" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>vahidnasiri</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7815821915651048578.post-6366129580065855316</guid><pubDate>Wed, 25 Jan 2012 20:46:00 +0000</pubDate><atom:updated>2012-01-26T00:18:20.554+03:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">WinRT</category><title>زير نويس فارسي ويديوهاي ساخت برنامه‌هاي مترو توسط سي شارپ و XAML - قسمت چهارم</title><description>&lt;div dir="rtl" style="text-align: right;" trbidi="on"&gt;&lt;br /&gt;
زيرنويس‌هاي فارسي قسمت چهارم «&lt;a href="http://www.pluralsight-training.net/microsoft/Courses/TableOfContents?courseName=win8-csxaml"&gt;Building Windows 8 Metro Apps in C# and XAML&lt;/a&gt;» را &lt;a href="http://dnps.codeplex.com/SourceControl/list/changesets"&gt;از اينجا&lt;/a&gt; و يا &lt;a href="https://dnps.svn.codeplex.com/svn/win8-csxaml/4-csxamlwinrt-listcontrols/"&gt;اينجا&lt;/a&gt; مي‌تونيد دريافت كنيد.&lt;br /&gt;
&lt;br /&gt;
ليست سرفصل‌هاي قسمت چهارم به شرح زير است:&lt;br /&gt;
&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="xml" name="code"&gt;List Controls  00:31:14 
This module shows the Metro controls available to XAML applications for working with collections of items.
This includes the new GridView and ListView controls, 
which are optimized for handling collections in a touch-based user interface. 

Introduction
Items Controls
Demo: ListBox vs ListView
Demo: GridView
Demo: FlipView 
Common ItemsControl
Semantic Zoom
Demo: JumpViewer
Summary
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
اين قسمت به بررسي يك سري كنترل ليستي جديد ويندوز 8 اختصاص دارد شامل ListView بازنويسي شده و همچنين GridView به همراه دو كنترل FlipView و JumpViewer كه تمام اين‌ها جهت كار با صفحات لمسي بهينه سازي شده‌اند.&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7815821915651048578-6366129580065855316?l=www.dotnettips.info' alt='' /&gt;&lt;/div&gt;</description><link>http://www.dotnettips.info/2012/01/xaml_26.html</link><author>noreply@blogger.com (وحيد نصيري)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7815821915651048578.post-2321996753355777923</guid><pubDate>Fri, 20 Jan 2012 10:38:00 +0000</pubDate><atom:updated>2012-01-20T14:08:04.761+03:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">WinRT</category><title>زير نويس فارسي ويديوهاي ساخت برنامه‌هاي مترو توسط سي شارپ و XAML - قسمت سوم</title><description>&lt;div dir="rtl" style="text-align: right;" trbidi="on"&gt;&lt;br /&gt;
زيرنويس‌هاي فارسي قسمت سوم «&lt;a href="http://www.pluralsight-training.net/microsoft/Courses/TableOfContents?courseName=win8-csxaml"&gt;Building Windows 8 Metro Apps in C# and XAML&lt;/a&gt;» را &lt;a href="http://dnps.codeplex.com/SourceControl/list/changesets"&gt;از اينجا&lt;/a&gt; و يا &lt;a href="https://dnps.svn.codeplex.com/svn/win8-csxaml/3-csxamlwinrt-controls/"&gt;اينجا&lt;/a&gt; مي‌تونيد دريافت كنيد.&lt;br /&gt;
&lt;br /&gt;
ليست سرفصل‌هاي قسمت سوم به شرح زير است:&lt;br /&gt;
&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="xml" name="code"&gt;Controls  00:48:08 
WinRT provides numerous XAML controls, which act as the building blocks of your applications.
Some of these will be familiar, while some are new to Metro. 
Introduction
Command Controls
Demo: Application Bar
Context Menus
Demo: Context Menus
Application Settings
CheckBox, RadioButton, and ToggleSwitch
Progress Controls
Demo: Progress Controls
Displaying Text
Demo: Displaying Text
Text Entry
Sliders
Styling
WebView
UserControl
Summary
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
مطالبي كه بيشتر در اين سري بر روي آن‌ها تمركز شده، مباحث صفحات لمسي و تغييرات كنترل‌هاي ويندوز 8 جهت سازگاري با اين مساله است. بنابراين در اين سري بيشتر از هرچيزي finger ، tap و touch را خواهيد شنيد. جايي كه چند جا را مي‌شود همزمان لمس كرد و با چندين انگشت همزمان كار كرد كه نكات قابل توجهي را نسبت به دنياي تك بعدي ماوس به همراه دارد.&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7815821915651048578-2321996753355777923?l=www.dotnettips.info' alt='' /&gt;&lt;/div&gt;</description><link>http://www.dotnettips.info/2012/01/xaml_20.html</link><author>noreply@blogger.com (وحيد نصيري)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7815821915651048578.post-9123470909667620602</guid><pubDate>Sun, 15 Jan 2012 06:53:00 +0000</pubDate><atom:updated>2012-01-15T10:57:12.957+03:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">WinRT</category><title>زير نويس فارسي ويديوهاي ساخت برنامه‌هاي مترو توسط سي شارپ و XAML - قسمت دوم</title><description>&lt;div dir="rtl" style="text-align: right;" trbidi="on"&gt;&lt;br /&gt;
زيرنويس‌هاي فارسي قسمت دوم «&lt;a href="http://www.pluralsight-training.net/microsoft/Courses/TableOfContents?courseName=win8-csxaml"&gt;Building Windows 8 Metro Apps in C# and XAML&lt;/a&gt;» را &lt;a href="http://dnps.codeplex.com/SourceControl/list/changesets"&gt;از اينجا&lt;/a&gt; و يا &lt;a href="https://dnps.svn.codeplex.com/svn/win8-csxaml/2-csxamlwinrt-layout/"&gt;اينجا&lt;/a&gt; مي‌تونيد دريافت كنيد.&lt;br /&gt;
&lt;br /&gt;
ليست سرفصل‌هاي قسمت دوم به شرح زير است:&lt;br /&gt;
&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="CSharp" name="code"&gt;Layout 00:46:16 
C# Metro applications have access to numerous XAML layout features. 
This module describes those services, and shows how to use them to support Windows 8 features such as display orientation, and snap. 

Introduction
Layout System
Size Properties
Alignment
Margin
Demo: Margin and Alignment 
Padding 
Panels 
Demo: Canvas 
Demo: Grid and Snap 
Data-Oriented Panels 
ScrollViewer 
Metro Layout Conventions 
Layout Change Events 
Summary
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
در كل اين قسمت هم آنچنان كاري به برنامه نويسي ندارد و به بررسي و معرفي امكانات طرحبندي XAML مي‌پردازد؛ به علاوه يك سري قراردادهاي خاص مترو و همچنين نحوه‌ي كنار آمدن با حالت snapping ويژه ويندوز 8.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
قسمت سوم مروري دارد بر كنترل‌هاي XAML كه حدودا يك هفته ديگر زيرنويس‌هاي آن تمام خواهد شد.&lt;br /&gt;
لطفا اگر پس از مشاهده اين سري آماده شده، اصلاحي را انجام داديد، اون رو براي اعمال &lt;a href="http://dnps.codeplex.com/SourceControl/list/patches"&gt;در اينجا&lt;/a&gt; ارسال كنيد. از &lt;a href="http://subtitletools.codeplex.com/"&gt;اين برنامه&lt;/a&gt; هم جهت ويرايش فايل‌ها مي‌توان استفاده كرد.&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7815821915651048578-9123470909667620602?l=www.dotnettips.info' alt='' /&gt;&lt;/div&gt;</description><link>http://www.dotnettips.info/2012/01/xaml_15.html</link><author>noreply@blogger.com (وحيد نصيري)</author><thr:total>5</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7815821915651048578.post-3683981294704553697</guid><pubDate>Fri, 13 Jan 2012 06:52:00 +0000</pubDate><atom:updated>2012-01-13T10:22:50.721+03:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">WinRT</category><title>زير نويس فارسي ويديوهاي ساخت برنامه‌هاي مترو توسط سي شارپ و XAML - قسمت اول</title><description>&lt;div dir="rtl" style="text-align: right;" trbidi="on"&gt;&lt;br /&gt;
سايت &lt;a href="http://www.pluralsight-training.net/microsoft/Courses#dotnet"&gt;pluralsight&lt;/a&gt; ويديوهاي آموزشي بسيار با كيفيتي را در مورد مباحث مختلف دات نت تا بحال تهيه كرده و تقريبا هر موضوع جديدي هم كه اضافه مي‌شود، بلافاصله يك سري جديد را تهيه مي‌كنند. مدرسين انتخابي هم عموما افراد نامدار و باسوادي هستند.&lt;br /&gt;
پروژه‌اي رو در سايت كدپلكس شروع كردم جهت تهيه زيرنويس فارسي براي اين ويديوها:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: center;"&gt;&lt;a dir="ltr" href="http://dnps.codeplex.com/"&gt;http://dnps.codeplex.com/&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
اين كار نسبت به كار تهيه زيرنويس‌هاي فارسي موجود براي فيلم‌هاي انگليسي كار سخت‌تري است به چند دليل:&lt;br /&gt;
- اسكريپت آماده‌اي وجود ندارد. كار شنيداري است.&lt;br /&gt;
- زمانبندي آماده‌اي وجود ندارد.&lt;br /&gt;
- مباحث تخصصي است.&lt;br /&gt;
- مدرس از ثانيه اول ويديو تا ثانيه آخر آن حرف مي‌زند!&lt;br /&gt;
&lt;br /&gt;
براي مثال جهت تهيه زيرنويس‌هاي فارسي فيلم‌هاي انگليسي عموما به سايت‌هايي مانند &lt;a href="http://alt.subscene.com/"&gt;subscene.com&lt;/a&gt; مراجعه مي‌شود. يك زيرنويس يا به قولي اسكريپت آماده يافت شده و شروع به ترجمه مي‌شود. متن آماده است. زمانبندي آماده است و فقط كار ترجمه باقي مي‌ماند.&lt;br /&gt;
اما در مورد ويديوهاي آموزشي انگليسي خير. به همين جهت در اين زمينه كار آنچناني تابحال صورت نگرفته.&lt;br /&gt;
كار زمانبري است. فعلا ركورد من براي هر سه دقيقه ويديوي آموزشي كه مدرس از ثانيه اول تا آخر آن حرف مي‌زند، 40 دقيقه كار تهيه زير نويس فارسي زمانبندي شده است.&lt;br /&gt;
&lt;br /&gt;
سري جديدي رو كه شروع كردم تحت عنوان «&lt;a href="http://www.pluralsight-training.net/microsoft/Courses/TableOfContents?courseName=win8-csxaml"&gt;Building Windows 8 Metro Apps in C# and XAML&lt;/a&gt;» در سايت pluralsight ارائه شده.&lt;br /&gt;
فعلا قسمت اول آن زيرنويس دار شده و &lt;a href="http://dnps.codeplex.com/SourceControl/list/changesets"&gt;از اينجا&lt;/a&gt; قابل دريافت است. براي مشاهده آن‌ها برنامه با كيفيت و رايگان &lt;a href="http://www.kmplayer.com/forums/forumdisplay.php?f=25"&gt;KMPlayer&lt;/a&gt; توصيه مي‌شود.&lt;br /&gt;
&lt;br /&gt;
ليست ويديوهاي قسمت اول آن به شرح زير است: &lt;br /&gt;
&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="xml" name="code"&gt;Building Windows 8 Metro Apps in C# and XAML 
Overview  00:50:41 
This modules provides an overview of how to develop Windows 8 Metro style applications in C# and XAML. 

Introduction
XAML and Codebehind
Asynchronous APIs
Demo: Asynchronous APIs
Files and Networking
Demo: Requesting Capabilities
Integrating with Windows 8
WinRT and .NET
Summary
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
كلمه سي شارپ در اين قسمت كمي غلط انداز است. بيشتر بحث و توضيح است تا كد نويسي. بنابراين براي عموم قابل استفاده است. خصوصا نگاهي دارد به تازه‌هاي ويندوز 8 از ديدگاه برنامه نويس‌ها مانند سطوح دسترسي برنامه‌هاي مترو، معرفي Charms ، نحوه به اشتراك گذاري اطلاعات در بين برنامه‌هاي مترو نصب شده، براي مثال جايي كه ديگر Clipboard سابق وجود ندارد و مواردي از اين دست.&lt;br /&gt;
&lt;br /&gt;
5 قسمت ديگر اين مبحث باقيمانده كه هر زمان تكميل شد، خبرش رو خواهيد شنيد و تقريبا از اين پس اين سايت به همين ترتيب جلو خواهد رفت. فكر مي‌كنم اينطوري مفيدتر باشد. هر از چندگاهي يك مبحث جديد زيرنويس دار شده را مي‌توانيد مشاهده كنيد.&lt;br /&gt;
&lt;br /&gt;
اگر علاقمند بوديد مي‌تونيد در اين پروژه شركت كنيد و يك موضوع جديد و مستقل را براي تهيه زيرنويس شروع كنيد. يا حداقل اگر پس از مشاهده اين سري آماده شده، اصلاحي را انجام داديد، مي‌تونيد اون رو براي اعمال &lt;a href="http://dnps.codeplex.com/SourceControl/list/patches"&gt;در اينجا&lt;/a&gt; ارسال كنيد.&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7815821915651048578-3683981294704553697?l=www.dotnettips.info' alt='' /&gt;&lt;/div&gt;</description><link>http://www.dotnettips.info/2012/01/xaml.html</link><author>noreply@blogger.com (وحيد نصيري)</author><thr:total>11</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7815821915651048578.post-210335736678601188</guid><pubDate>Tue, 10 Jan 2012 20:42:00 +0000</pubDate><atom:updated>2012-01-11T00:12:32.987+03:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">Refactoring</category><title>مروري بر كدهاي كلاس SqlHelper</title><description>&lt;div dir="rtl" style="text-align: right;" trbidi="on"&gt;&lt;br /&gt;
قسمتي از يك پروژه به همراه كلاس SqlHelper آن در كامنت‌هاي مطلب «&lt;a href="http://www.dotnettips.info/2012/01/code-review.html"&gt;اهميت Code review&lt;/a&gt;» توسط يكي از خوانندگان بلاگ جهت Code review مطرح شده كه بهتر است در يك مطلب جديد و مجزا به آن پرداخته شود. قسمت مهم آن كلاس SqlHelper است و مابقي در اينجا نديد گرفته مي‌شوند:&lt;br /&gt;
&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="CSharp" name="code"&gt;//It's only for code review purpose!  
using System.Data;
using System.Data.SqlClient;
using System.Web.Configuration;


public sealed class SqlHelper
{
    private SqlHelper() { }

    
    //  Send Connection String
    //---------------------------------------------------------------------------------------
    public static string GetCntString()
    {
        return WebConfigurationManager.ConnectionStrings["db_ConnectionString"].ConnectionString;
    }

   
    //  Connect to Data Base SqlServer
    //---------------------------------------------------------------------------------------
    public static SqlConnection Connect2Db(ref SqlConnection sqlCnt, string cntString)
    {
        try
        {
            if (sqlCnt == null) sqlCnt = new SqlConnection();
            sqlCnt.ConnectionString = cntString;
            if (sqlCnt.State != ConnectionState.Open) sqlCnt.Open();
            return sqlCnt;
        }
        catch (SqlException)
        {
            return null;
        }
    }

  
    //  Run ExecuteScalar Command
    //---------------------------------------------------------------------------------------
    public static string RunExecuteScalarCmd(ref SqlConnection sqlCnt, string strCmd, bool blnClose)
    {
        Connect2Db(ref sqlCnt, GetCntString());
        using (sqlCnt)
        {
            using(SqlCommand sqlCmd = sqlCnt.CreateCommand())
            {
                sqlCmd.CommandText = strCmd;
                object objResult = sqlCmd.ExecuteScalar();
                if (blnClose) CloseCnt(ref sqlCnt, true);
                return (objResult == null) ? string.Empty : objResult.ToString();
            }
        }
    }

    //   Close SqlServer Connection
    //---------------------------------------------------------------------------------------
    public static bool CloseCnt(ref SqlConnection sqlCnt, bool nullSqlCnt)
    {
        try
        {
            if (sqlCnt == null) return true;
            if (sqlCnt.State == ConnectionState.Open)
            {
                sqlCnt.Close();
                sqlCnt.Dispose();
            }
            if (nullSqlCnt) sqlCnt = null;
            return true;
        }
        catch (SqlException)
        {
            return false;
        }
    }   
}
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
مثالي از نحوه استفاده ارائه شده:&lt;br /&gt;
&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="CSharp" name="code"&gt;protected void BtnTest_Click(object sender, EventArgs e)
        {
            SqlConnection sqlCnt = new SqlConnection();
            string strQuery = "SELECT COUNT(UnitPrice) AS PriceCount FROM [Order Details]";


            // در این مرحله پارامتر سوم یعنی کانکشن باز نگه داشته شود
            string strResult = SqlHelper.RunExecuteScalarCmd(ref sqlCnt, strQuery, false);



            strQuery = "SELECT LastName + N'-' + FirstName AS FullName FROM Employees WHERE (EmployeeID = 9)";
            // در این مرحله پارامتر سوم یعنی کانکشن بسته شود
            strResult = SqlHelper.RunExecuteScalarCmd(ref sqlCnt, strQuery, true);
        }
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;مروري بر اين كد:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;1) نحوه كامنت نوشتن&lt;/b&gt;&lt;br /&gt;
بين سي شارپ و زبان سي++ تفاوت وجود دارد. اين نحوه كامنت نويسي بيشتر در سي++ متداول است. اگر از ويژوال استوديو استفاده مي‌كنيد، مكان نما را به سطر قبل از يك متد منتقل كرده و سه بار پشت سر هم forward slash را تايپ كنيد. به صورت خودكار ساختار خالي زير تشكيل خواهد شد:&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="CSharp" name="code"&gt;/// &amp;lt;summary&amp;gt;
    /// 
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name="sqlCnt"&amp;gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name="cntString"&amp;gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
    public static SqlConnection Connect2Db(ref SqlConnection sqlCnt, string cntString)
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
اين روش مرسوم كامنت نويسي كدهاي سي شارپ است. خصوصا اينكه ابزارهايي وجود دارند كه به صورت خودكار از اين نوع كامنت‌ها، فايل CHM‌ درست مي‌كنند.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;2) وجود سازنده private&lt;/b&gt;&lt;br /&gt;
احتمالا هدف اين بوده كه نه شخصي و نه حتي كامپايلر، وهله‌اي از اين كلاس را ايجاد نكند. بنابراين بهتر است كلاسي را كه تمام متدهاي آن static است (كه به اين هم خواهيم رسيد!) ، راسا static معرفي كنيد. به اين ترتيب نيازي به سازنده private نخواهد بود.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;3) وجود try/catch&lt;/b&gt;&lt;br /&gt;
يك اصل كلي وجود دارد: اگر در حال طراحي يك كتابخانه پايه‌اي هستيد، try/catch را در هيچ متدي از آن لحاظ نكنيد. بله؛ درست خونديد! لطفا try/catch ننويسيد! كرش كردن برنامه خوب است! لا‌يه‌هاي بالاتر برنامه كه در حال استفاده از كدهاي شما هستند متوجه خواهند شد كه مشكلي رخ داده و اين مشكل توسط كتابخانه مورد استفاده «خفه» نشده. براي مثال اگر هم اكنون SQL Server در دسترس نيست، لايه‌هاي بالاتر برنامه بايد اين مشكل را متوجه شوند. Exception اصلا چيز بدي نيست! كرش برنامه اصلا بد نيست! &lt;br /&gt;
فرض كنيد كه دچار بيماري شده‌ايد. اگر مثلا تبي رخ ندهد، از كجا بايد متوجه شد كه نياز به مراقبت پزشكي وجود دارد؟ اگر هيچ علامتي بروز داده نشود كه تا الان نسل بشر منقرض شده بود!&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;4) وجود ref و out&lt;/b&gt;&lt;br /&gt;
دوستان گرامي! اين ref و out فقط جهت سازگاري با زبان C در سي شارپ وجود دارد. لطفا تا حد ممكن از آن استفاده نكنيد! مثلا استفاده از توابع API‌ ويندوز كه با C نوشته شده‌اند.&lt;br /&gt;
يكي از مهم‌ترين كاربردهاي pointers در زبان سي، دريافت بيش از يك خروجي از يك تابع است. براي مثال يك متد API ويندوز را فراخواني مي‌كنيد؛ خروجي آن يك ساختار است كه به كمك pointers به عنوان يكي از پارامترهاي همان متد معرفي شده. اين روش به وفور در طراحي ويندوز بكار رفته. ولي خوب در سي شارپ كه از اين نوع مشكلات وجود ندارد. يك كلاس ساده را طراحي كنيد كه چندين خاصيت دارد. هر كدام از اين خاصيت‌ها مي‌توانند نمايانگر يك خروجي باشند. خروجي متد را از نوع اين كلاس تعريف كنيد. يا براي مثال در دات نت 4، امكان ديگري به نام Tuples معرفي شده براي كساني كه سريع مي‌خواهند چند خروجي از يك تابع دريافت كنند و نمي‌خواهند براي اينكار يك كلاس بنويسند.&lt;br /&gt;
ضمن اينكه براي مثال در متد Connect2Db، هم كانكشن يكبار به صورت ref معرفي شده و يكبار به صورت خروجي متد. اصلا نيازي به استفاده از ref در اينجا نبوده. حتي نيازي به خروجي كانكشن هم در اين متد وجود نداشته. كليه تغييرات شما در شيء كانكشني كه به عنوان پارامتر ارسال شده، در خارج از آن متد هم منعكس مي‌شود (شبيه به همان بحث pointers در زبان سي). بنابراين وجود ref غيرضروري است؛ وجود خروجي متد هم به همين صورت. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;5) استفاده از using در متد RunExecuteScalarCmd&lt;/b&gt;&lt;br /&gt;
استفاده از using خيلي خوب است؛ هميشه اينكار را انجام دهيد! &lt;br /&gt;
اما اگر اينكار را انجام داديد، بدانيد كه شيء sqlCnt در پايان بدنه using ، توسط  GC نابوده شده است. بنابراين اينجا bool blnClose ديگر چه كاربردي دارد؟! تصميم شما ديگر اهميتي نخواهد داشت؛ چون كار تخريبي پيشتر انجام شده.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;6) متد CloseCnt&lt;/b&gt;&lt;br /&gt;
اين متد زايد است؛ به دليلي كه در قسمت (5) عنوان شد. using هاي استفاده شده، كار را تمام كرده‌اند. بنابراين بستن اشياء dispose شده معنا نخواهد داشت.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;7) در مورد نحوه استفاده&lt;/b&gt;&lt;br /&gt;
اگر SqlHelper را در اينجا مثلا يك DAL ساده فرض كنيم (data access layer)، جاي قسمت BLL (business logic layer) در اينجا خالي است. عموما هم چون توضيحات اين موارد را خيلي بد ارائه داده‌اند، افراد از شنيدن اسم آن‌ها هم وحشت مي‌كنند. BLL يعني كمي دست به Refactoring بزنيد و اين پياده سازي منطق تجاري ارائه شده در متد BtnTest_Click را به يك كلاس مجزا خارج از code behind پروژه منتقل كنيد. Code behind فقط محل استفاده نهايي از آن باشد. همين! فعلا با همين مختصر شروع كنيد.&lt;br /&gt;
مورد ديگري كه در اينجا باز هم مشهود است، عدم استفاده از پارامتر در كوئري‌ها است. چون از پارامتر استفاده نكرده‌ايد، SQL Server مجبور است براي حالت EmployeeID = 9 يكبار execution plan را محاسبه كند، براي كوئري بعدي مثلا EmployeeID = 19، اينكار را تكرار كند و الي آخر. اين يعني مصرف حافظه بالا و همچنين سرعت پايين انجام كوئري‌ها. بنابراين اينقدر در قيد و بند باز نگه داشتن يك كانكشن نباشيد؛ مشكل اصلي جاي ديگري است!&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;8) برنامه وب و اطلاعات استاتيك!&lt;/b&gt;&lt;br /&gt;
اين پروژه، يك پروژه ASP.NET است. ديدن تعاريف استاتيك در اين نوع پروژه‌ها يك علامت خطر است! در اين مورد قبلا مطلب نوشتم:&lt;br /&gt;
&lt;a href="http://www.dotnettips.info/2010/12/aspnet.html"&gt;متغيرهاي استاتيك و برنامه‌هاي ASP.NET&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;يك درخواست عمومي!&lt;/b&gt;&lt;br /&gt;
لطف كنيد در پروژ‌هاي «جديد» خودتون اين نوع كلاس‌هاي SqlHelper رو «دور بريزيد». ياد گرفتن كار با يك ORM جديد اصلا سخت نيست. مثلا طراحي Entity framework مايكروسافت به حدي ساده است كه هر شخصي با داشتن بهره هوشي در حد يك عنكبوت آبي يا حتي جلبك دريايي هم مي‌تونه با اون كار كنه! فقط NHibernate هست كه كمي مرد افكن است و گرنه مابقي به عمد ساده طراحي شده‌اند.&lt;br /&gt;
مزاياي كار كردن با ORM ها اين است:&lt;br /&gt;
- كوئري‌هاي حاصل از آن‌ها «پارامتري» است؛ كه اين دو مزيت عمده را به همراه دارد:&lt;br /&gt;
امنيت: مقاومت در برابر SQL Injection&lt;br /&gt;
سرعت و همچنين مصرف حافظه كمتر: با كوئري‌هاي پارامتري در SQL Server همانند رويه‌هاي ذخيره شده رفتار مي‌شود.&lt;br /&gt;
- عدم نياز به نوشتن DAL شخصي پر از باگ. چون ORM يعني همان DAL كه توسط يك سري حرفه‌اي طراحي شده.&lt;br /&gt;
- يك دست شدن كدها در يك تيم. چون همه بر اساس يك اينترفيس مشخص كار خواهند كرد.&lt;br /&gt;
- امكان استفاده از امكانات جديد زبان‌هاي دات نتي مانند LINQ و نوشتن كوئري‌هاي strongly typed تحت كنترل كامپايلر.&lt;br /&gt;
- پايين آوردن هزينه‌هاي آموزشي افراد در يك تيم. مثلا EF را مي‌شود به عنوان يك پيشنياز در نظر گرفت؛ عمومي است و همه گير. كسي هم از شنيدن نام آن تعجب نخواهد كرد. كتاب(هاي) آموزشي هم در مورد آن زياد هست.&lt;br /&gt;
و ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7815821915651048578-210335736678601188?l=www.dotnettips.info' alt='' /&gt;&lt;/div&gt;</description><link>http://www.dotnettips.info/2012/01/sqlhelper.html</link><author>noreply@blogger.com (وحيد نصيري)</author><thr:total>23</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7815821915651048578.post-3609120441451142042</guid><pubDate>Tue, 10 Jan 2012 18:28:00 +0000</pubDate><atom:updated>2012-01-10T21:58:00.020+03:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">Unit testing</category><title>قبل از رفع باگ، براي آن تست بنويسيد</title><description>&lt;div dir="rtl" style="text-align: right;" trbidi="on"&gt;&lt;br /&gt;
از دقت كردن در نحوه اداره  پروژه‌هاي خوب و بزرگ در سطح دنيا، مي‌توان به نكات آموزنده‌اي رسيد. براي مثال NHibernate را درنظر بگيريد. اين پروژه شايد روز اول كپي مطابق اصل نمونه جاواي آن بوده، اما الان از خيلي از جهات يك سر و گردن از آن بالاتر است. پشتيباني LINQ را اضافه كرده، خودش Syntax جديدي را به نام QueryOver ارائه داده و همچنين معادلي را جهت حذف فايل‌هاي XML به كمك امكانات جديد زبان‌هاي دات نتي مانند lambda expressions ارائه كرده. خلاصه اين تيم، فقط يك كپي كار نيست. پايه رو از يك جايي گرفته اما سبب تحول در آن شده. از اهداف پروژه‌هاي سورس باز هم همين است: براي هر كاري چرخ را از صفر ابداع نكنيد.&lt;br /&gt;
&lt;br /&gt;
اگر به نحوه اداره كلي پروژه NHibernate‌ دقت كنيد يك مورد مشهود است:&lt;br /&gt;
&lt;ul style="text-align: right;"&gt;&lt;li&gt;تمام گزارش‌هاي باگ بدون Unit test نديد گرفته مي‌شوند.&lt;/li&gt;
&lt;li&gt;از كليه بهبودهاي ارائه شده (وصله‌ها يا patch ها) بدون Unit test صرفنظر مي‌شود.&lt;/li&gt;
&lt;li&gt;از كليه موارد جديد ارائه شده بدون Unit test هم صرفنظر خواهد شد.&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
بنابراين اگر در issue tracker اين تيم رفتيد و گفتيد: «سلام، اينجا اين مشكل هست»، خيالتان راحت باشد كه نديد گرفته خواهيد شد.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;سؤال : چرا اين‌ها اينطور رفتار مي‌كنند؟!&lt;/b&gt;&lt;br /&gt;
- وجود Unit test دقيقا مشخص مي‌كند كه چه قسمت يا قسمت‌هايي به گزارش باگ شما مرتبط هستند. نيازي نيست حتما بتوانيد يك خطا را با جملات ساده شرح دهيد. اين مساله خصوصا در پروژه‌هاي بين المللي حائز اهميت است. ضعف زبان انگليسي همه جا هست. همينقدر كه توانسته‌ايد براي آن يك Unit test بنويسيد كه مثلا در اين عمليات با اين ورودي،‌ نتيجه قرار بوده بشود 10 و مثلا شده 5 يا حتي اين Exception صادر شده كه بايد كنترل شود، يعني مشكل را كاملا مشخص كرده‌ايد. &lt;br /&gt;
- وجود Unit tests ، انجام Code review و همچنين Refactoring را تسهيل مي‌بخشند. در هر دو حالت ياد شده، هدف تغيير كاركرد سيستم نيست؛ هدف بهبود كيفيت كدهاي موجود است. بنابراين دست به يك سري تغييرات زده خواهد شد. اما سؤال اينجا است كه از كجا بايد مطمئن شد كه اين تغييرات، سيستم را به هم نريخته‌اند. پروژه‌ي جاري چند سال است كه در حال توسعه است. قسمت‌هاي زيادي به آن اضافه شده. با نبود Unit tests ممكن است بعضي از قسمت‌ها زايد يا احمقانه به نظر برسند.&lt;br /&gt;
- بهترين مستندات كدهاي تهيه شده، Unit tests آن هستند. براي مثال علاقمند هستيد كه NHibernate را ياد بگيريد؟ هرچه مي‌گرديد مثال‌هاي كمي را در اينترنت در اين زمينه پيدا مي‌كنيد؟ وقت خودتان را تلف نكنيد! اين پروژه بالاي 2000 آزمون واحد دارد. هر كدام از اين آزمون‌ها نحوه‌ي بكارگيري قسمت‌هاي مختلف را به نحوي كاربردي بيان مي‌كنند.&lt;br /&gt;
- وجود Unit tests از پيدايش مجدد باگ‌ها جلوگيري مي‌كنند. اگر آزمون واحدي وجود نداشته باشد، امروز كدي اضافه مي‌شود. فردا همين كد توسط عده‌اي ديگر زايد تشخيص داده شده و حذف مي‌شود! بنابراين احتمال بروز مجدد اين خطا در آينده وجود خواهد داشت. با وجود Unit tests، فلسفه وجودي هر قسمتي از كدهاي موجود پروژه دقيقا مشخص مي‌شود و در صورت حذف آن‌، با اجراي آزمون‌هاي خودكار سريعا مي‌توان به كمبودهاي حاصل پي‌برد.&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7815821915651048578-3609120441451142042?l=www.dotnettips.info' alt='' /&gt;&lt;/div&gt;</description><link>http://www.dotnettips.info/2012/01/blog-post_10.html</link><author>noreply@blogger.com (وحيد نصيري)</author><thr:total>4</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7815821915651048578.post-8999426526893309911</guid><pubDate>Sun, 08 Jan 2012 13:55:00 +0000</pubDate><atom:updated>2012-01-08T17:25:04.045+03:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">CHM</category><category domain="http://www.blogger.com/atom/ns#">Tips</category><title>وادار كردن خود به كامنت نوشتن</title><description>&lt;div dir="rtl" style="text-align: right;" trbidi="on"&gt;&lt;br /&gt;
قابليت جالبي در ويژوال استوديو وجود دارد كه شايد كمتر در مورد آن مطلب نوشته شده است و آن هم تنظيم پروژه به نحوي است كه اگر براي كليه موارد public كامنتي نوشته نشود، برنامه كامپايل نخواهد شد. همچنين اگر نام پارامتري را تغيير داديد، اما كامنت مرتبط با آن را به روز نكرديد، باز هم خطاي كامپايل را دريافت خواهيد كرد كه از اين لحاظ هم بسيار عالي است و به نوعي «وادار كردن خود به كامنت نوشتن» است.&lt;br /&gt;
&lt;br /&gt;
براي اين تنظيم، ابتدا به برگه خواص پروژه مراجعه كنيد. سپس در قسمت Build تنظيمات زير را اعمال نمائيد:&lt;br /&gt;
Treat warnings as errors را بر روي All قرار دهيد.&lt;br /&gt;
در ذيل آن، در قسمت Output‌، گزينه‌ي XML Documentation file را تيك بزنيد.&lt;br /&gt;
&lt;br /&gt;
البته اين تغيير بهتر است در يك پروژه جديد مد نظر باشد، چون اگر الان اقدام به اين تنظيم كنيد، به طور قطع از خير آن خواهيد گذشت! كامنت نويسي به مرور و در حين توسعه يك برنامه يا كتابخانه قابل تحمل است وگرنه اگر براي روز آخر قرار داده شود، به احتمال زياد انجام نخواهد شد.&lt;br /&gt;
&lt;br /&gt;
مطالب مرتبط:&lt;br /&gt;
&lt;ul style="text-align: right;"&gt;&lt;li&gt;&lt;a href="http://www.dotnettips.info/2008/11/chm-xml.html"&gt;درست كردن فايل راهنماي CHM از توضيحات XML يك پروژه&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.dotnettips.info/2011/09/blog-post_27.html"&gt;اضافه كردن كامنت جهت فضاهاي نام&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7815821915651048578-8999426526893309911?l=www.dotnettips.info' alt='' /&gt;&lt;/div&gt;</description><link>http://www.dotnettips.info/2012/01/blog-post_08.html</link><author>noreply@blogger.com (وحيد نصيري)</author><thr:total>4</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7815821915651048578.post-8329462810497777428</guid><pubDate>Fri, 06 Jan 2012 10:40:00 +0000</pubDate><atom:updated>2012-01-06T14:14:19.354+03:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">Refactoring</category><category domain="http://www.blogger.com/atom/ns#">Tips</category><title>اهميت code review</title><description>&lt;div dir="rtl" style="text-align: right;" trbidi="on"&gt;&lt;br /&gt;
تا جايي كه دقت كردم (در بلاگ‌هايي كه منتشر مي‌شوند) در آنسوي آب‌ها، «&lt;a href="http://www.codinghorror.com/blog/2006/01/code-reviews-just-do-it.html"&gt;code review&lt;/a&gt;» يك شغل محسوب مي‌شود. سازمان‌ها، شركت‌ها و امثال آن از مشاورين يا برنامه نويس‌هايي با مطالعه بيشتر دعوت مي‌كنند تا از كدهاي آن‌ها اشكال‌گيري كنند و بابت اينكار هم هزينه مي‌كنند.&lt;br /&gt;
اگر علاقمند باشيد قسمتي از يك پروژه سورس باز دريافت شده از همين دور و اطراف را با هم مرور كنيم:&lt;br /&gt;
&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="CSharp" name="code"&gt;//It's only for code review purpose!
protected void Button1_Click1(object sender, EventArgs e)
{        
        string  strcon;        
        string strUserURL;
        string strSQL;
        string strSQL1;
        strSQL = "SELECT UserLevel FROM listuser " + "WHERE Username='" + TextBox2.Text + "' " + "And Password='" + TextBox3.Text + "';";
        strSQL1 = "SELECT Pnumber FROM listuser " + "WHERE Username='" + TextBox2.Text + "' " + "And Password='" + TextBox3.Text + "';";
        strcon = @"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\bimaran.mdf;Integrated Security=True;User Instance=True";
        SqlConnection myConnection = new SqlConnection(strcon);

        SqlCommand myCommand = new SqlCommand(strSQL, myConnection);
        SqlCommand myCommand1 = new SqlCommand(strSQL1, myConnection);
        myConnection.Open();

        strUserURL = (string)myCommand.ExecuteScalar();
        send = (string)myCommand1.ExecuteScalar();
        myCommand.Dispose();
        myCommand1.Dispose();
        myConnection.Close();


        if (strUserURL != null)
        {                      
            Label1.Text = "";

            url = "?Pn=" + code(send);
            FormsAuthentication.SetAuthCookie(TextBox2.Text, true);
            Response.Redirect("Page/" + strUserURL + url);
       }
        else
            Label3.Text = "چنین کاربری با این مشخصات ثبت نشده است.";
}
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
مروري بر اين كد يا «مشكلات اين كد»:&lt;br /&gt;
- كانكشن استرينگ داخل كدها تعريف شده. يعني اگر نياز به تغييري در آن بود بايد كدهاي برنامه تغيير كنند. آن هم نه فقط در اين تابع بلكه در كل برنامه.&lt;br /&gt;
- از پارامتر استفاده نشده. كد 100 درصد به تزريق اس كيوال آسيب پذير است.&lt;br /&gt;
- نحوه‌ي dispose شيء كانكشن غلط است. هيچ ضمانتي وجود ندارد كه كدهاي فوق سطر به سطر اجرا شود و خيلي زيبا به سطر بستن كانكشن استرينگ برسد. فقط كافي است اين ميان يك استثنايي صادر شود و تمام. به عبارتي اين سايت فقط با كمتر از 30 كاربر همزمان از كار مي‌افته. بعد نيايد بگيد من يك سرور دارم با 16 گيگ رم ولي باز كم مياره! همش برنامه كند ميشه. همش سايت بالا نمياد!&lt;br /&gt;
- همين تعريف كردن متغيرها در ابتداي تابع يعني اين برنامه نويس هنوز حال و هواي ANSI C را دارد!&lt;br /&gt;
- مهم نيست لايه بندي كنيد. ولي يك لايه در اين نوع پروژه‌ها الزامي است و آن هم DAL نام دارد. DAL يعني كثافت كاري نكنيد. يعني داخل هر تابع كُپه كُپه بر نداريد open  و close بذاريد. بريد يك تابع يك گوشه‌اي درست كنيد كه اين عمليات را محصور كند. &lt;br /&gt;
- همين وجود Button1 و Label1 يعني تو خود شرح مفصل بخوان از اين مجمل!&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7815821915651048578-8329462810497777428?l=www.dotnettips.info' alt='' /&gt;&lt;/div&gt;</description><link>http://www.dotnettips.info/2012/01/code-review.html</link><author>noreply@blogger.com (وحيد نصيري)</author><thr:total>33</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7815821915651048578.post-6670264540490336592</guid><pubDate>Fri, 06 Jan 2012 05:54:00 +0000</pubDate><atom:updated>2012-01-06T09:24:30.761+03:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">others</category><title>اندرباب اهميت به اشتراك گذاري اطلاعات</title><description>&lt;div dir="rtl" style="text-align: right;" trbidi="on"&gt;&lt;br /&gt;
&lt;ul style="text-align: right;"&gt;&lt;li&gt;&lt;a href="http://www.lessonsoffailure.com/software/habit-4-never-share-information/"&gt;از ويژگي‌هاي برنامه نويس‌هاي سازماني: هيچگاه اطلاعاتي را به اشتراك نگذاريد!&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;&lt;a href="http://www.jeffblankenburg.com/2012/01/03/be-a-creator-not-a-consumer/"&gt;توليد كننده باشيد، نه مصرف كننده&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;&lt;a href="http://www.hanselman.com/blog/YourBlogIsTheEngineOfCommunity.aspx"&gt;بلاگ شما نيروي محركه جامعه اطلاعاتي است&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;&lt;a href="http://kaarmand.blogfa.com/post-196.aspx"&gt;از رموز پيشرفت غرب: مستند سازي اطلاعات و تجربه‌ها&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;&lt;a href="http://michaelcrump.net/11-things-every-software-developer-should-be-doing-in-2012"&gt;11 كاري كه بهتر است برنامه نويس‌ها در سال جديد انجام دهند&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;&lt;a href="http://channel9.msdn.com/Shows/HanselminutesOn9/Hanselminutes-on-9-Social-Networking-for-Developers-Part-1-Every-Developer-Needs-a-Blog"&gt;هر برنامه نويس نياز به يك بلاگ دارد&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;&lt;a href="http://www.moneyaside.com/why-every-freelancer-should-have-a-blog"&gt;چرا هر برنامه نويس نياز به يك بلاگ دارد&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7815821915651048578-6670264540490336592?l=www.dotnettips.info' alt='' /&gt;&lt;/div&gt;</description><link>http://www.dotnettips.info/2012/01/blog-post.html</link><author>noreply@blogger.com (وحيد نصيري)</author><thr:total>4</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7815821915651048578.post-5128563111735755151</guid><pubDate>Wed, 04 Jan 2012 10:50:00 +0000</pubDate><atom:updated>2012-01-04T14:20:19.450+03:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">iTextSharp</category><title>تعيين تعداد رديف در صفحه جداول خودكار iTextSharp</title><description>&lt;div dir="rtl" style="text-align: right;" trbidi="on"&gt;&lt;br /&gt;
پيشنياز : «&lt;a href="http://www.dotnettips.info/2011/07/itextsharp_24.html"&gt;تكرار خودكار سرستون‌هاي يك جدول در صفحات مختلف، توسط iTextSharp&lt;/a&gt;»&lt;br /&gt;
همانطور كه در مطلب پيشنياز عنوان شده ذكر گرديد، iTextSharp امكان درج خودكار header و footer به علاوه محاسبه خودكار تعداد رديف‌هاي يك جدول در يك صفحه را بر اساس طول و اندازه محتواي هر رديف، دارد. براي مثال يك صفحه ممكن است 2 رديف شود و يك صفحه 20 رديف. تمام اين‌ها را به صورت خودكار محاسبه مي‌كند و بسيار عالي است. (اين امكان مهمي است كه خيلي از ابزارهاي گزارشگيري موجود هنوز با آن مشكل دارند)&lt;br /&gt;
اما اگر فرض را بر اين بگذاريم كه اندازه سلول‌ها و در نتيجه طول هر رديف ثابت است و مثلا تمام صفحات نهايتا از يك تعداد رديف مشخص تشكيل خواهند شد، خاصيتي را به نام number of rows يا rows count و امثال آن‌را ندارد كه مثلا به آن گفت، من در هر صفحه فقط 5 رديف را مي‌خواهم نمايش دهم و نه 20 رديف را. &lt;br /&gt;
روش حل اين مساله را در ادامه ملاحظه خواهيد كرد و يك نكته‌ي خيلي ساده و مستند نشده دارد!&lt;br /&gt;
&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="CSharp" name="code"&gt;using System.Diagnostics;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;

namespace RowsCountSample
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var pdfDoc = new Document(PageSize.A4))
            {
                var pdfWriter = PdfWriter.GetInstance(pdfDoc, new FileStream("Test.pdf", FileMode.Create));
                pdfDoc.Open();

                var table1 = new PdfPTable(3);
                table1.HeaderRows = 2;
                table1.FooterRows = 1;

                //header row  
                var headerCell = new PdfPCell(new Phrase("header"));
                headerCell.Colspan = 3;
                headerCell.HorizontalAlignment = Element.ALIGN_CENTER;
                table1.AddCell(headerCell);

                //footer row  
                var footerCell = new PdfPCell(new Phrase("footer"));
                footerCell.Colspan = 3;
                footerCell.HorizontalAlignment = Element.ALIGN_CENTER;
                table1.AddCell(footerCell);

                //adding some rows  
                for (int i = 0; i &amp;lt; 70; i++)
                {
                    //adds a new row
                    table1.AddCell(new Phrase("Cell[0], Row[" + i + "]"));
                    table1.AddCell(new Phrase("Cell[1], Row[" + i + "]"));
                    table1.AddCell(new Phrase("Cell[2], Row[" + i + "]"));

                    //sets the number of rows per page
                    if (i &amp;gt; 0 &amp;amp;&amp;amp; table1.Rows.Count % 7 == 0)
                    {
                        pdfDoc.Add(table1);
                        table1.DeleteBodyRows();
                        pdfDoc.NewPage();
                    }
                }

                pdfDoc.Add(table1);
            }

            //open the final file with adobe reader for instance.  
            Process.Start("Test.pdf");
        }
    }
}
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
نكته جديد اين مثال، قسمت زير است:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="CSharp" name="code"&gt;if (i &amp;gt; 0 &amp;amp;&amp;amp; table1.Rows.Count % 7 == 0)
{
      pdfDoc.Add(table1);
      table1.DeleteBodyRows();
      pdfDoc.NewPage();
}
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
هر زمان كه table1 به صفحه اضافه شود، header و footer هم اضافه خواهند شد، اما اگر BodyRows آن حذف نشود،‌ دفعه‌ي دومي كه اين table به صفحه اضافه مي‌شود، شامل رديف‌هاي مثلا يك تا 10 خواهد بود بجاي 6 تا 10 .&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7815821915651048578-5128563111735755151?l=www.dotnettips.info' alt='' /&gt;&lt;/div&gt;</description><link>http://www.dotnettips.info/2012/01/itextsharp.html</link><author>noreply@blogger.com (وحيد نصيري)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7815821915651048578.post-1568960363514547429</guid><pubDate>Tue, 03 Jan 2012 07:20:00 +0000</pubDate><atom:updated>2012-01-03T10:50:29.370+03:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">Security</category><category domain="http://www.blogger.com/atom/ns#">iTextSharp</category><title>نصب خودكار اطلاعات فايل‌هاي PFX در سيستم</title><description>&lt;div dir="rtl" style="text-align: right;" trbidi="on"&gt;&lt;br /&gt;
در مورد نحوه رمزنگاري فايل‌هاي PDF به كمك روش Public-key encryption توسط  iTextSharp &lt;a href="http://www.dotnettips.info/2011/11/pdf-itextsharp.html"&gt;مطلبي را&lt;/a&gt; پيشتر در اين سايت مطالعه كرده‌ايد.&lt;br /&gt;
اين روش يك مشكل مهم دارد: «ارائه فايل PFX و همچنين كلمه عبور آن به كاربر نهايي»&lt;br /&gt;
خوب، اين يعني اينكه شما به راحتي مي‌تونيد اطلاعات را رمزگشايي كنيد؛ چون همه چيز سخاوتمندانه در اختيارتان است. بنابراين ضرورت رمزنگاري آن در ابتداي امر زير سؤال مي‌رود.&lt;br /&gt;
اكنون اين سؤال مطرح مي‌شود كه آيا مي‌توان اين اطلاعات را تا حد قابل قبولي مخفي كرد؟ مثلا يك برنامه را در اختيار كاربر قرار داد كه اطلاعات فايل PFX را به همراه كلمه عبور آن در سيستم نصب كند.&lt;br /&gt;
پاسخ:&lt;br /&gt;
دات نت به صورت توكار از اين نوع فايل‌هاي مجوز پشتيباني مي‌كند:&lt;br /&gt;
&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="CSharp" name="code"&gt;using System.Security.Cryptography.X509Certificates;

namespace InstallPfx
{
    class Program
    {
        private static void InstallCertificate(string cerFileName, string password)
        {
            var certificate = new X509Certificate2(cerFileName, password, X509KeyStorageFlags.PersistKeySet);
            var store = new X509Store(StoreName.My);
            store.Open(OpenFlags.ReadWrite);
            store.Add(certificate);
            store.Close();
        }

        static void Main(string[] args)
        {
            InstallCertificate(@"D:\forTest\file.pfx", "123456");
        }
    }
}
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
پس از اجراي كد فوق، امكان مشاهده فايل‌هاي PDF رمزنگاري شده به كمك اطلاعات فايل file.pfx، ميسر مي‌شود.&lt;br /&gt;
براي مشاهده اين مجوز نصب شده هم مي‌توان در ديالوگ Run ويندوز نوشت : certmgr.msc تا كنسول مديريتي مجوز‌هاي ويندوز ظاهر شود. سپس به قسمت personal certificates بايد مراجعه كرد.&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7815821915651048578-1568960363514547429?l=www.dotnettips.info' alt='' /&gt;&lt;/div&gt;</description><link>http://www.dotnettips.info/2012/01/pfx.html</link><author>noreply@blogger.com (وحيد نصيري)</author><thr:total>3</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7815821915651048578.post-8383929932629945986</guid><pubDate>Mon, 02 Jan 2012 06:41:00 +0000</pubDate><atom:updated>2012-01-02T10:13:30.773+03:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">MVVM</category><title>MVVM و نمايش ديالوگ‌ها</title><description>&lt;div dir="rtl" style="text-align: right;" trbidi="on"&gt;&lt;br /&gt;
بسياري از برنامه‌هاي دسكتاپ نياز به نمايش پنجره‌هاي ديالوگ استاندارد ويندوز مانند OpenFileDialog  و  SaveFileDialog را دارند و سؤال اينجا است كه چگونه اينگونه موارد را بايد از طريق پياده سازي صحيح الگوي MVVM مديريت كرد؛ از آنجائيكه خيلي راحت در فايل ViewModel مي‌توان نوشت new OpenFileDialog و الي آخر. اين مورد هم يكي از دلايل اصلي استفاده از الگوي MVVM را زير سؤال مي‌برد : اين ViewModel ديگر قابل تست نخواهد بود. هميشه شرايط آزمون‌هاي واحد را به اين صورت در نظر بگيريد:&lt;br /&gt;
سروري وجود دارد در جايي كه به آن دسترسي نداريم. روي اين سرور با اتوماسيوني كه راه انداخته‌ايم، آخر هر روز آزمون‌هاي واحد موجود به صورت خودكار انجام شده و يك گزارش تهيه مي‌شود (مثلا يك نوع &lt;a href="http://en.wikipedia.org/wiki/Continuous_integration"&gt;continuous integration&lt;/a&gt; سرور). بنابراين كسي دسترسي به سرور نخواهد داشت تا اين OpenFileDialog ظاهر شده را مديريت كرده، فايلي را انتخاب و به برنامه آزمون واحد معرفي كند. به صورت خلاصه ظاهر شدن هر نوع ديالوگي حين انجام آزمون‌هاي واحد «مسخره» است!&lt;br /&gt;
يكي از روش‌هاي حل اين نوع مسايل، استفاده از dependency injection يا تزريق وابستگي‌ها است و در ادامه خواهيم ديد كه چگونه WPF‌ بدون نياز به هيچ نوع فريم ورك تزريق وابستگي خارجي، از اين مفهوم پشتيباني مي‌كند.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;مروري مقدماتي بر تزريق وابستگي‌ها&lt;/b&gt;&lt;br /&gt;
امكان نوشتن آزمون واحد براي new OpenFileDialog وجود ندارد؟ اشكالي نداره، يك Interface بر اساس نياز نهايي برنامه درست كنيد (نياز نهايي برنامه از اين ماجرا فقط يك رشته LoadPath است و بس) سپس در ViewModel با اين اينترفيس كار كنيد؛ چون به اين ترتيب امكان «&lt;a href="http://en.wikipedia.org/wiki/Mock_object"&gt;تقليد&lt;/a&gt;» آن فراهم مي‌شود.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;يك مثال عملي:&lt;/b&gt;&lt;br /&gt;
ViewModel نياز دارد تا مسير فايلي را از كاربر بپرسد. اين مساله را با كمك &lt;a href="http://www.dotnettips.info/2009/12/dependency-injection.html"&gt;dependency injection&lt;/a&gt; در ادامه حل خواهيم كرد.&lt;br /&gt;
ابتدا سورس كامل اين مثال:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;ViewModel برنامه&lt;/b&gt; (تعريف شده در پوشه ViewModels برنامه):&lt;br /&gt;
&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="CSharp" name="code"&gt;namespace WpfFileDialogMvvm.ViewModels
{
    public interface IFilePathContract
    {
        string GetFilePath();       
    }

    public class MainWindowViewModel
    {
        IFilePathContract _filePathContract;
        public MainWindowViewModel(IFilePathContract filePathContract)
        {
            _filePathContract = filePathContract;
        }

        //...

        private void load()
        {
            string loadFilePath = _filePathContract.GetFilePath();
            if (!string.IsNullOrWhiteSpace(loadFilePath))
            {
                // Do something
            }
        }
    }
}
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
دو نمونه از پياده سازي اينترفيس IFilePathContract تعريف شده (در پوشه Dialogs برنامه):&lt;br /&gt;
&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="CSharp" name="code"&gt;using Microsoft.Win32;
using WpfFileDialogMvvm.ViewModels;

namespace WpfFileDialogMvvm.Dialogs
{
    public class OpenFileDialogProvider : IFilePathContract
    {
        public string GetFilePath()
        {
            var ofd = new OpenFileDialog
            {
                Filter = "XML files (*.xml)|*.xml"
            };
            string filePath = null;
            bool? dialogResult = ofd.ShowDialog();
            if (dialogResult.HasValue &amp;amp;&amp;amp; dialogResult.Value)
            {
                filePath = ofd.FileName;
            }
            return filePath;
        }
    }

    public class FakeOpenFileDialogProvider : IFilePathContract
    {
        public string GetFilePath()
        {
            return @"c:\path\data.xml";
        }
    }
}
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
&lt;b&gt;و View برنامه:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="XML" name="code"&gt;&amp;lt;Window x:Class="WpfFileDialogMvvm.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="clr-namespace:WpfFileDialogMvvm.ViewModels"
        xmlns:dialogs="clr-namespace:WpfFileDialogMvvm.Dialogs"
        Title="MainWindow" Height="350" Width="525"&amp;gt;
    &amp;lt;Window.Resources&amp;gt;        
        &amp;lt;ObjectDataProvider x:Key="mainWindowViewModel" 
                            ObjectType="{x:Type vm:MainWindowViewModel}"&amp;gt;
            &amp;lt;ObjectDataProvider.ConstructorParameters&amp;gt;
                &amp;lt;dialogs:OpenFileDialogProvider/&amp;gt;
            &amp;lt;/ObjectDataProvider.ConstructorParameters&amp;gt;
        &amp;lt;/ObjectDataProvider&amp;gt;
    &amp;lt;/Window.Resources&amp;gt;
    &amp;lt;Grid DataContext="{Binding Source={StaticResource mainWindowViewModel}}"&amp;gt;
        
    &amp;lt;/Grid&amp;gt;
&amp;lt;/Window&amp;gt;
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
&lt;b&gt;توضيحات:&lt;/b&gt;&lt;br /&gt;
ما در ViewModel نياز داريم تا مسير نهايي فايل را دريافت كنيم و اين عمليات نياز به فراخواني متد ShowDialog ايي را دارد كه امكان نوشتن آزمون واحد خودكار را از ViewModel ما سلب خواهد كرد. بنابراين بر اساس نياز برنامه يك اينترفيس عمومي به نام IFilePathContract را طراحي مي‌كنيم. در حالت كلي كلاسي كه اين اينترفيس را پياده سازي مي‌كند، قرار است مسيري را برگرداند. اما به كمك استفاده از اينترفيس، به صورت ضمني اعلام مي‌كنيم كه «براي ما مهم نيست كه چگونه». مي‌خواهد OpenFileDialogProvider ذكر شده باشد، يا نمونه تقليدي مانند FakeOpenFileDialogProvider. از نمونه واقعي OpenFileDialogProvider در برنامه اصلي استفاده خواهيم كرد، از نمونه تقليدي FakeOpenFileDialogProvider در آزمون واحد و نكته مهم هم اينجا است كه ViewModel ما چون بر اساس اينترفيس IFilePathContract پياده سازي شده، با هر دو DialogProvider ياد شده مي‌تواند كار كند.&lt;br /&gt;
مرحله آخر نوبت به وهله سازي نمونه واقعي، در View برنامه است. يا مي‌توان در Code behind مرتبط با View نوشت:&lt;br /&gt;
&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="CSharp" name="code"&gt;namespace WpfFileDialogMvvm
{
    public partial class MainWindow
    {
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = new MainWindowViewModel(new OpenFileDialogProvider());
        }
    }
}
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
و يا از روش ObjectDataProvider توكار WPF هم مي‌شود استفاده كرد؛ كه مثال آن‌را در كدهاي XAML مرتبط با View ذكر شده مي‌توانيد مشاهده كنيد. ابتدا دو فضاي نام vm و dialog تعريف شده (با توجه به اينكه مثلا در اين مثال، دو پوشه ViewModels و Dialogs وجود دارند). سپس كار تزريق وابستگي‌ها به سازنده كلاس MainWindowViewModel،‌ از طريق ObjectDataProvider.ConstructorParameters انجام مي‌شود:&lt;br /&gt;
&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="XML" name="code"&gt;&amp;lt;ObjectDataProvider x:Key="mainWindowViewModel" 
                            ObjectType="{x:Type vm:MainWindowViewModel}"&amp;gt;
            &amp;lt;ObjectDataProvider.ConstructorParameters&amp;gt;
                &amp;lt;dialogs:OpenFileDialogProvider/&amp;gt;
            &amp;lt;/ObjectDataProvider.ConstructorParameters&amp;gt;
&amp;lt;/ObjectDataProvider&amp;gt;
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7815821915651048578-8383929932629945986?l=www.dotnettips.info' alt='' /&gt;&lt;/div&gt;</description><link>http://www.dotnettips.info/2012/01/mvvm.html</link><author>noreply@blogger.com (وحيد نصيري)</author><thr:total>5</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7815821915651048578.post-8015116153307523830</guid><pubDate>Sat, 31 Dec 2011 08:50:00 +0000</pubDate><atom:updated>2011-12-31T12:20:55.396+03:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">MVVM</category><title>MVVM و فراخواني متدهاي اشياء View از طريق ViewModel</title><description>&lt;div dir="rtl" style="text-align: right;" trbidi="on"&gt;&lt;br /&gt;
ما در ViewModel دسترسي مستقيمي به هيچ يك از اشياء موجود در View نداريم (و درستش هم همين است). الان فرض كنيد كه مي‌خواهيم از طريق ViewModel يك View را ببنديم؛ مثلا متد Close آن پنجره را فراخواني كنيم. به عبارتي در حالت كلي مي‌خواهيم يكي از متدهاي تعريف شده يكي از عناصر بصري موجود در View را از طريق ViewModel فراخواني نمائيم.&lt;br /&gt;
براي حل اين مساله از فايل‌هاي همان &lt;a href="http://www.microsoft.com/download/en/details.aspx?displaylang=en&amp;amp;id=10801"&gt;SDK‌ مرتبط با Expression blend&lt;/a&gt; استفاده خواهيم كرد.&lt;br /&gt;
&lt;br /&gt;
ابتدا ارجاعاتي را به اسمبلي‌هاي System.Windows.Interactivity.dll  و Microsoft.Expression.Interactions.dll اضافه مي‌كنيم.&lt;br /&gt;
سپس دو فضاي نام مرتبط هم بايد اضافه شوند:&lt;br /&gt;
&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="XML" name="code"&gt;&amp;nbsp;&amp;nbsp;xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
&lt;b&gt;يك مثال عملي:&lt;/b&gt;&lt;br /&gt;
قصد داريم از طريق ViewModel ، پنجره‌اي را ببنديم. كدهاي XAML اين مثال را در ادامه مشاهده خواهيد كرد:&lt;br /&gt;
&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="XML" name="code"&gt;&amp;lt;Window x:Class="WpfCallMethodActionSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
        xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
        xmlns:vm="clr-namespace:WpfCallMethodActionSample.ViewModels" 
        Name="ThisWindow"
        Title="MainWindow" Height="350" Width="525"&amp;gt;
    &amp;lt;Window.Resources&amp;gt;
        &amp;lt;vm:MainWindowViewModel x:Key="vmMainWindowViewModel" /&amp;gt;
    &amp;lt;/Window.Resources&amp;gt;
    &amp;lt;Grid DataContext="{Binding Source={StaticResource vmMainWindowViewModel}}"&amp;gt;

        &amp;lt;Button Content="Save &amp;amp;amp; Close" VerticalAlignment="Top" Margin="5"&amp;gt;            
            &amp;lt;i:Interaction.Triggers&amp;gt;
                &amp;lt;!--فراخواني متدي در ويوو مدل--&amp;gt;
                &amp;lt;i:EventTrigger EventName="Click"&amp;gt;
                    &amp;lt;ei:CallMethodAction 
                            TargetObject="{Binding}"
                            MethodName="SaveButtonClicked" /&amp;gt;
                &amp;lt;/i:EventTrigger&amp;gt;

                &amp;lt;!--فراخواني متدي در شيء جاري از طريق ويوو مدل--&amp;gt;
                &amp;lt;i:EventTrigger SourceObject="{Binding}"  EventName="CloseMainWindow"&amp;gt;
                    &amp;lt;ei:CallMethodAction
                            TargetObject="{Binding ElementName=ThisWindow}"
                            MethodName="Close"/&amp;gt;
                &amp;lt;/i:EventTrigger&amp;gt;
            &amp;lt;/i:Interaction.Triggers&amp;gt;            
        &amp;lt;/Button&amp;gt;
    &amp;lt;/Grid&amp;gt;
&amp;lt;/Window&amp;gt;
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
همچنين ViewModel تعريف شده نيز همين چند سطر زير است:&lt;br /&gt;
&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="CSharp" name="code"&gt;using System;

namespace WpfCallMethodActionSample.ViewModels
{
    public class MainWindowViewModel
    {
        public void SaveButtonClicked()
        {
            close();
        }

        public event EventHandler CloseMainWindow;
        private void close()
        {
            if (CloseMainWindow != null) CloseMainWindow(this, EventArgs.Empty);
        }
    }
}
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
توضيحات:&lt;br /&gt;
اگر به ViewModel دقت كنيد خبري از DelegateCommand در آن نيست. بله، به كمك تركيبي از EventTrigger و CallMethodAction مي‌توان جايگزيني را جهت DelegateCommand معرفي شده در قسمت‌هاي قبل اين سري مباحث MVVM ارائه داد.&lt;br /&gt;
EventTrigger در اينجا به اين معنا است كه اگر EventName ذكر شده رخ داد، آنگاه اين اعمال را انجام بده. مثلا در اينجا CallMethodAction را فراخواني كن.&lt;br /&gt;
CallMethodAction در اسمبلي Microsoft.Expression.Interactions.dll تعريف شده است و تنها متدي از نوع void و بدون پارامتر را مي‌تواند به صورت خودكار فراخواني كند (محدوديت مهم آن است). &lt;br /&gt;
اينكه اين متد كجا قرار دارد، توسط TargetObject آن مشخص مي‌شود. اگر TargetObject را مساوي Binding قرار داديم، يعني به دنبال متدي كه در DataContext گريد وجود دارد بگرد. به عبارتي به صورت خودكار به SaveButtonClicked تعريف شده در ViewModel ما متصل خواهد شد و آن‌را فراخواني مي‌كند.&lt;br /&gt;
&lt;br /&gt;
تا اينجا رخداد Click دكمه تعريف شده را به متد SaveButtonClicked موجود در ViewModel سيم كشي كرديم.&lt;br /&gt;
&lt;br /&gt;
در مرحله بعد مي‌خواهيم از طريق ViewModel ، متدي را در View فراخواني كنيم. نكته آن هم پيشتر ذكر شد؛ TargetObject صحيحي را بايد انتخاب كرد. در اينجا براي پنجره جاري نام ThisWindow تعريف شده است و از طريق تعريف:&lt;br /&gt;
&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="XML" name="code"&gt;TargetObject="{Binding ElementName=ThisWindow}"
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
به CallMethodAction خواهيم گفت كه قرار است متد Close را در شيء ThisWindow فراخواني كني.&lt;br /&gt;
همچنين نحوه تعريف EventTrigger ما هم در اينجا برعكس شده است:&lt;br /&gt;
&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="XML" name="code"&gt;&amp;lt;i:EventTrigger SourceObject="{Binding}"  EventName="CloseMainWindow"&amp;gt;
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
قبلا به دنبال مثلا رخداد Click يك دكمه بوديم، اكنون با توجه به SourceObject تعريف شده، در ViewModel به دنبال اين رخداد كه براي نمونه در اينجا CloseMainWindow نام گرفته خواهيم گشت.&lt;br /&gt;
&lt;br /&gt;
بنابراين View اينبار به رخداد CloseMainWindow تعريف شده در ViewModel سيم كشي خواهد شد. اكنون اگر اين رخداد در ViewModel فراخواني شود، CallMethodAction متناظر فعال شده و متد Close پنجره را فراخواني مي‌كند.&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7815821915651048578-8015116153307523830?l=www.dotnettips.info' alt='' /&gt;&lt;/div&gt;</description><link>http://www.dotnettips.info/2011/12/mvvm-view-viewmodel.html</link><author>noreply@blogger.com (وحيد نصيري)</author><thr:total>26</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7815821915651048578.post-2447971996168370143</guid><pubDate>Wed, 28 Dec 2011 06:55:00 +0000</pubDate><atom:updated>2011-12-28T10:25:07.500+03:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">MVVM</category><title>MVVM و رويدادگرداني - قسمت دوم</title><description>&lt;div dir="rtl" style="text-align: right;" trbidi="on"&gt;&lt;br /&gt;
قسمت اول اين بحث و همچنين پيشنياز آن‌را در &lt;a href="http://www.dotnettips.info/2011/12/mvvm_14.html"&gt;اينجا&lt;/a&gt; و &lt;a href="http://www.dotnettips.info/2011/12/delegatecommand.html"&gt;اينجا&lt;/a&gt; مي‌توانيد مطالعه نمائيد.&lt;br /&gt;
همه‌ي اين‌ها بسيار هم نيكو! اما ... آيا واقعا بايد به ازاي هر روال رويدادگرداني يك Attached property نوشت تا بتوان از آن در الگوي MVVM استفاده كرد؟ براي يكي دو مورد شايد اهميتي نداشته باشد؛ اما كم كم با بزرگتر شدن برنامه نوشتن اين Attached properties تبديل به يك كار طاقت فرسا مي‌شود و اشخاص را از الگوي MVVM فراري خواهد داد.&lt;br /&gt;
براي حل اين مساله، تيم Expression Blend راه حلي را ارائه داده‌اند به نام Interaction.Triggers كه در ادامه به توضيح آن پرداخته خواهد شد.&lt;br /&gt;
ابتدا نياز خواهيد داشت تا SDK‌ مرتبط با Expression Blend را دريافت كنيد: &lt;a href="http://www.microsoft.com/download/en/details.aspx?displaylang=en&amp;amp;id=10801"&gt;(^)&lt;/a&gt;&lt;br /&gt;
سپس با فايل System.Windows.Interactivity.dll موجود در آن كار خواهيم داشت.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;يك مثال عملي:&lt;/b&gt;&lt;br /&gt;
فرض كنيد مي‌خواهيم رويداد Loaded يك View را در ViewModel دريافت كنيم. زمان وهله سازي يك ViewModel با زمان وهله سازي View يكي است، اما بسته به تعداد عناصر رابط كاربري قرار گرفته در View ، زمان بارگذاري نهايي آن ممكن است متفاوت باشد به همين جهت رويداد Loaded براي آن درنظر گرفته شده است. خوب، ما الان در ViewModel نياز داريم بدانيم كه چه زماني كار بارگذاري يك View  به پايان رسيده. &lt;br /&gt;
يك راه حل آن‌را در قسمت قبل مشاهده كرديد؛ بايد براي اين كار يك Attached property جديد نوشت چون نمي‌توان Command ايي را به رويداد Loaded انتساب داد يا Bind كرد. اما به كمك امكانات تعريف شده در System.Windows.Interactivity.dll به سادگي مي‌توان اين رويداد را به يك Command استاندارد ترجمه كرد:&lt;br /&gt;
&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="xml" name="code"&gt;&amp;lt;Window x:Class="WpfEventTriggerSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
        xmlns:vm="clr-namespace:WpfEventTriggerSample.ViewModels"
        Title="MainWindow" Height="350" Width="525"&amp;gt;
    &amp;lt;Window.Resources&amp;gt;
        &amp;lt;vm:MainWindowViewModel x:Key="vmMainWindowViewModel" /&amp;gt;
    &amp;lt;/Window.Resources&amp;gt;
    &amp;lt;Grid DataContext="{Binding Source={StaticResource vmMainWindowViewModel}}"&amp;gt;
        &amp;lt;i:Interaction.Triggers&amp;gt;
            &amp;lt;i:EventTrigger EventName="Loaded"&amp;gt;
                &amp;lt;i:InvokeCommandAction Command="{Binding DoLoadCommand}" 
                                       CommandParameter="I am loaded!" /&amp;gt;
            &amp;lt;/i:EventTrigger&amp;gt;
        &amp;lt;/i:Interaction.Triggers&amp;gt;

        &amp;lt;TextBlock Text="Testing InvokeCommandAction..." 
                   Margin="5" VerticalAlignment="Top" /&amp;gt;
    &amp;lt;/Grid&amp;gt;
&amp;lt;/Window&amp;gt;
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
ابتدا ارجاعي به اسمبلي System.Windows.Interactivity.dll بايد به پروژه اضافه شود. سپس فضاي نام  xmlns:i بايد به فايل XAML جاري مطابق كدهاي فوق اضافه گردد. در نهايت به كمك Interaction.Triggers آن، ابتدا نام رويداد مورد نظر را مشخص مي‌كنيم (EventName) و سپس به كمك InvokeCommandAction، اين رويداد به يك Command استاندارد ترجمه مي‌شود.&lt;br /&gt;
ViewModel اين View هم مي‌تواند به شكل زير باشد كه با كلاس DelegateCommand آن در &lt;a href="http://www.dotnettips.info/2011/12/delegatecommand.html"&gt;پيشنيازهاي&lt;/a&gt; بحث جاري آشنا شده‌ايد.&lt;br /&gt;
&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="CSharp" name="code"&gt;using WpfEventTriggerSample.Helper;

namespace WpfEventTriggerSample.ViewModels
{
    public class MainWindowViewModel
    {
        public DelegateCommand&amp;lt;string&amp;gt; DoLoadCommand { set; get; }
        public MainWindowViewModel()
        {
            DoLoadCommand = new DelegateCommand&amp;lt;string&amp;gt;(doLoadCommand, canDoLoadCommand);
        }

        private void doLoadCommand(string param)
        {
            //do something
        }

        private bool canDoLoadCommand(string param)
        {
            return true;
        }
    }
}
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
به اين ترتيب حجم قابل ملاحظه‌اي از كد نويسي Attached properties مورد نياز، به ساده‌ترين شكل ممكن، كاهش خواهد يافت. &lt;br /&gt;
بديهي است اين Interaction.Triggers را جهت تمام عناصر UI ايي كه حداقل يك رويداد منتسب تعريف شده داشته باشند، مي‌توان بكار گرفت؛ مثلا تبديل رويداد Click يك دكمه به يك Command استاندارد:&lt;br /&gt;
&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="XML" name="code"&gt;&amp;lt;Button&amp;gt;
            &amp;lt;i:Interaction.Triggers&amp;gt;
                &amp;lt;i:EventTrigger EventName="Click"&amp;gt;
                    &amp;lt;i:InvokeCommandAction Command="{Binding DoClick}" 
                                       CommandParameter="I am loaded!" /&amp;gt;
                &amp;lt;/i:EventTrigger&amp;gt;
            &amp;lt;/i:Interaction.Triggers&amp;gt;
&amp;lt;/Button&amp;gt;

&lt;/pre&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7815821915651048578-2447971996168370143?l=www.dotnettips.info' alt='' /&gt;&lt;/div&gt;</description><link>http://www.dotnettips.info/2011/12/mvvm_28.html</link><author>noreply@blogger.com (وحيد نصيري)</author><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7815821915651048578.post-9140814928282404656</guid><pubDate>Sun, 25 Dec 2011 10:30:00 +0000</pubDate><atom:updated>2011-12-25T14:04:34.359+03:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">MVVM</category><category domain="http://www.blogger.com/atom/ns#">WPF</category><title>MVVM و الگوي ViewModel Locator</title><description>&lt;div dir="rtl" style="text-align: right;" trbidi="on"&gt;&lt;br /&gt;
اگر ViewModel را همان فايل code behind عاري از ارجاعاتي به اشياء بصري بدانيم، يك تفاوت مهم را علاوه بر مورد ذكر شده نسبت به Code behind متداول خواهد داشت: وهله سازي آن بايد دستي انجام شود و خودكار نيست.&lt;br /&gt;
اگر به ابتداي كلاس‌هاي code behind‌ دقت كنيد هميشه واژه‌ي partial قابل رويت است، به اين معنا كه اين كلاس در حقيقت جزئي از همان كلاس متناظر با XAML ايي است كه مشاهده مي‌كنيد؛ يا به عبارتي با آن يكي است. فقط جهت زيبايي يا مديريت بهتر، در دو كلاس قرار گرفته‌اند اما واژه كليدي partial اين‌ها را نهايتا به صورت يكسان و يكپارچه‌اي به كامپايلر معرفي خواهد كرد. بنابراين وهله سازي code behind هم خودكار خواهد بود و به محض نمايش رابط كاربري،‌ فايل code behind آن هم وهله سازي مي‌شود؛ چون اساسا و در پشت صحنه، از ديدگاه كامپايلر تفاوتي بين اين دو وجود ندارد.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;اكنون سؤال اينجا است كه آيا مي‌توان با ViewModel ها هم همين وهله سازي خودكار را به محض نمايش يك View متناظر، پياده سازي كرد؟ &lt;/b&gt;&lt;br /&gt;
البته صحيح آن اين است كه عنوان شود ViewModel متناظر با يك View و نه برعكس. چون روابط در الگوي MVVM از View به ViewModel به Model است و نه حالت عكس؛ مدل نمي‌داند كه ViewModel ايي وجود دارد. ViewModel هم از وجود View ها در برنامه بي‌خبر است و اين «بي‌خبري‌ها» اساس الگوهايي مانند MVC ، MVVM ، MVP‌ و غيره هستند. به همين جهت &lt;a href="http://ganjoor.net/attar/divana/ghazal-attar/sh394/"&gt;شاعر&lt;/a&gt; در وصف ViewModel فرموده‌اند كه:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: center;"&gt;اي در درون برنامه‌ام و View از تو بي خبر_________وز تو برنامه‌ام پر است و برنامه از تو بي خبر :)&lt;/div&gt;&lt;br /&gt;
&lt;b&gt;پاسخ:&lt;/b&gt;&lt;br /&gt;
بله. براي اين منظور الگوي ديگري به نام &lt;a href="http://stackoverflow.com/a/5462324/298573"&gt;ViewModel Locator&lt;/a&gt; طراحي شده است؛ روش‌هاي &lt;a href="https://www.google.com/search?q=viewmodel+locator"&gt;زيادي&lt;/a&gt; براي پياده سازي اين الگو وجود دارند كه ساده‌ترين آن‌ها مورد زير است:&lt;br /&gt;
فرض كنيد ViewModel ساده زير را قصد داريم به كمك الگوي ViewModel Locator به View ايي تزريق كنيم:&lt;br /&gt;
&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="CSharp" name="code"&gt;namespace WpfViewModelLocator.ViewModels
{
    public class MainWindowViewModel
    {
        public string SomeText { set; get; }
        public MainWindowViewModel()
        {
            SomeText = "Data ...";
        }
    }
}
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
براي اين منظور ابتدا كلاس ViewModelLocatorBase زير را تدارك خواهيم ديد:&lt;br /&gt;
&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="CSharp" name="code"&gt;using WpfViewModelLocator.ViewModels;

namespace WpfViewModelLocator.ViewModelLocator
{
    public class ViewModelLocatorBase
    {
        public MainWindowViewModel MainWindowVm
        {
            get { return new MainWindowViewModel(); }
        }
    }
}
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
در اينجا يك وهله از كلاس MainWindowViewModel توسط خاصيتي به نام MainWindowVm در دسترس قرار خواهد گرفت. براي اينكه بتوان اين كلاس را در تمام Viewهاي برنامه قابل دسترسي كنيم، آن‌را در App.Xaml تعريف خواهيم كرد:&lt;br /&gt;
&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="XML" name="code"&gt;&amp;lt;Application x:Class="WpfViewModelLocator.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:vml="clr-namespace:WpfViewModelLocator.ViewModelLocator"
             StartupUri="MainWindow.xaml"&amp;gt;
    &amp;lt;Application.Resources&amp;gt;
        &amp;lt;vml:ViewModelLocatorBase x:Key="ViewModelLocatorBase" /&amp;gt;
    &amp;lt;/Application.Resources&amp;gt;
&amp;lt;/Application&amp;gt;
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
اكنون فقط كافي است در View خود DataContext را به نحو زير مقدار دهي كنيم تا در زمان اجرا به صورت خودكار بتوان به خاصيت MainWindowVm ياد شده دسترسي يافت:&lt;br /&gt;
&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="XML" name="code"&gt;&amp;lt;Window x:Class="WpfViewModelLocator.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        
        Title="MainWindow" Height="350" Width="525"&amp;gt;
    &amp;lt;Grid DataContext="{Binding Path=MainWindowVm, Source={StaticResource ViewModelLocatorBase}}"&amp;gt;
        &amp;lt;TextBlock Text="{Binding SomeText}" VerticalAlignment="Top" Margin="5" /&amp;gt;
    &amp;lt;/Grid&amp;gt;
&amp;lt;/Window&amp;gt;
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
در مورد ViewModel ها و Viewهاي ديگر هم به همين ترتيب خواهد بود. يك وهله از آن‌ها به كلاس ViewModelLocatorBase اضافه مي‌شود. سپس Binding Path مرتبط به DataContext به نام خاصيتي كه در كلاس ViewModelLocatorBase مشخص خواهيم كرد، Bind خواهد شد.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;روش دوم:&lt;/b&gt;&lt;br /&gt;
اگر در اينجا بخواهيم Path را حذف كنيم و فقط دسترسي عمومي به ViewModelLocatorBase را ذكر كنيم، بايد يك Converter نوشت (چون به اين ترتيب مي‌توان به اطلاعات Binding در متد Convert دسترسي يافت). سپس يك قرار داد را هم تعريف خواهيم كرد؛ به اين صورت كه ما در Converter به نام View دسترسي پيدا مي‌كنيم (از طريق ريفلكشن). سپس نام viewModel ايي را كه بايد به دنبال آن گشت مثلا ViewName  به علاوه كلمه ViewModel در نظر خواهيم گرفت. در حقيقت يك نوع Convection over configuration است:&lt;br /&gt;
&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="CSharp" name="code"&gt;using System;
using System.Globalization;
using System.Linq;
using System.Windows.Data;

namespace WpfViewModelLocator.ViewModelLocator
{
    public class ViewModelLocatorBaseConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            //مقدار در اينجا همان مشخصات ويوو است
            if (value == null) return null;
            string viewTypeName = value.GetType().Name;

            //قرار داد ما است
            //ViewModel Name = ViewName + "ViewModel"
            string viewModelName = string.Concat(viewTypeName, "ViewModel");

            //يافتن اسمبلي كه حاوي ويوو مدل ما است
            var asms = AppDomain.CurrentDomain.GetAssemblies();
            var viewModelAsmName = "WpfViewModelLocator"; //نام پروژه مرتبط
            var viewModelAsm = asms.Where(x =&amp;gt; x.FullName.Contains(viewModelAsmName)).First();

            //يافتن اين كلاس ويوو مدل مرتبط
            var viewModelType = viewModelAsm.GetTypes().Where(x =&amp;gt; x.FullName.Contains(viewModelName)).FirstOrDefault();
            if (viewModelType == null)
                throw new InvalidOperationException(string.Format("Could not find view model '{0}'", viewModelName));

            //وهله سازي خودكار آن
            return Activator.CreateInstance(viewModelType);
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
كار اين تبديلگر بسيار ساده و واضح است. Value‌ دريافتي، وهله‌اي از view است. پس به اين ترتيب مي‌توان نام آن‌را يافت. سپس قرارداد ويژه خودمان را اعمال مي‌كنيم به اين ترتيب كه ViewModel Name = ViewName + "ViewModel" و سپس به دنبال اسمبلي كه حاوي اين نام است خواهيم گشت. آن‌را يافته، كلاس مرتبط را در آن پيدا مي‌كنيم و در آخر، به صورت خودكار آن‌را وهله سازي خواهيم كرد.&lt;br /&gt;
اينبار تعريف عمومي اين Conveter در فايل App.Xaml به صورت زير خواهد بود:&lt;br /&gt;
&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="XML" name="code"&gt;&amp;lt;Application x:Class="WpfViewModelLocator.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:vml="clr-namespace:WpfViewModelLocator.ViewModelLocator"
             StartupUri="MainWindow.xaml"&amp;gt;
    &amp;lt;Application.Resources&amp;gt;
        &amp;lt;vml:ViewModelLocatorBaseConverter x:Key="ViewModelLocatorBaseConverter" /&amp;gt;
    &amp;lt;/Application.Resources&amp;gt;
&amp;lt;/Application&amp;gt;
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
و استفاده‌ي آن در تمام View هاي برنامه به شكل زير مي‌باشد (بدون نياز به ذكر هيچ نام خاصي و بدون نياز به كلاس ViewModelLocatorBase ياد شده در ابتداي مطلب):&lt;br /&gt;
&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="XML" name="code"&gt;&amp;lt;Window x:Class="WpfViewModelLocator.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                
        DataContext="{Binding RelativeSource={RelativeSource Self}, 
                              Converter={StaticResource ViewModelLocatorBaseConverter}}"
        Title="MainWindow" Height="350" Width="525"&amp;gt;
    &amp;lt;Grid&amp;gt;
        &amp;lt;TextBlock Text="{Binding SomeText}" VerticalAlignment="Top" Margin="5" /&amp;gt;
    &amp;lt;/Grid&amp;gt;
&amp;lt;/Window&amp;gt;
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7815821915651048578-9140814928282404656?l=www.dotnettips.info' alt='' /&gt;&lt;/div&gt;</description><link>http://www.dotnettips.info/2011/12/mvvm-viewmodel-locator.html</link><author>noreply@blogger.com (وحيد نصيري)</author><thr:total>8</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7815821915651048578.post-2697849167141893912</guid><pubDate>Fri, 23 Dec 2011 18:03:00 +0000</pubDate><atom:updated>2011-12-23T21:33:42.202+03:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">News</category><title>خلاصه اشتراک‌های روز جمعه 2 دي 1390</title><description>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;div dir='rtl' align='right'&gt;&lt;br/&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://www.dotnetdev.info/2011/12/what-is-interface-segregation-principle.html' dir='rtl'&gt;اصل Interface Segregation چیست؟&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;www.dotnetdev.info&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://vsblogger.blogfa.com/post-20.aspx' dir='rtl'&gt;چند نکته در مورد فیلد Identity در SQL&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;vsblogger.blogfa.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://www.winbeta.net/%d9%87%d9%85%da%a9%d8%a7%d8%b1%db%8c-%da%af%d9%88%da%af%d9%84-%d9%85%d9%88%d8%b2%db%8c%d9%84%d8%a7/' dir='rtl'&gt;گوگل سالانه 300 میلیون دلار به موزیلا پرداخت می کند&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;www.winbeta.net&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://www.winbeta.net/%d8%a7%d9%85%da%a9%d8%a7%d9%86-%d8%ad%d8%b0%d9%81-%d8%af%d8%b3%d8%aa%d8%b1%d8%b3%db%8c-%d8%a8%d9%87-%d8%a7%db%8c%d9%86%d8%aa%d8%b1%d9%86%d8%aa/' dir='rtl'&gt;وزیر ارتباطات : دسترسی به اینترنت ممکن است حذف شود&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;www.winbeta.net&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://www.sharepointjohn.com/fixed-64-bit-adobe-pdf-previewer-in-outlook-20072010-and-windows-explorer/' dir='ltr'&gt;FIXED – 64-bit Adobe PDF Previewer&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;www.sharepointjohn.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://linqlib.codeplex.com/' dir='ltr'&gt;LINQ Extensions Library&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;linqlib.codeplex.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://www.microsoft.com/download/en/details.aspx?id=28568&amp;amp;WT.mc_id=rss_alldownloads_all' dir='ltr'&gt;Reactive Extensions (Rx) v1.0.10621 SP1&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;www.microsoft.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://cseweb.ucsd.edu/~hovav/papers/rbss11.html' dir='ltr'&gt;Return-Oriented Programming&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;cseweb.ucsd.edu&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://michaelcrump.net/11-things-every-software-developer-should-be-doing-in-2012' dir='rtl'&gt;11 کاری که هر برنامه نویس بهتر است در سال 2012 انجام دهد&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;michaelcrump.net&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://rmanimaran.wordpress.com/2011/03/20/xml-find-max-and-min-value-in-a-attribute-using-xpath-and-linq/' dir='ltr'&gt;Max &amp;amp; Min in LINQ to XML&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;rmanimaran.wordpress.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://www.codeproject.com/KB/cs/roslyn.aspx' dir='rtl'&gt;سه پروژه آغازین با Roslyn&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;www.codeproject.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://blogs.msdn.com/b/nickkramer/archive/2011/12/23/silverlight-security-overview-paper-has-been-updated-for-silverlight-5.aspx' dir='rtl'&gt;مروری بر مباحث امنیتی سیلورلایت 5&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;blogs.msdn.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7815821915651048578-2697849167141893912?l=www.dotnettips.info' alt='' /&gt;&lt;/div&gt;</description><link>http://www.dotnettips.info/2011/12/2-1390.html</link><author>noreply@blogger.com (وحيد نصيري)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7815821915651048578.post-5530092946537580267</guid><pubDate>Thu, 22 Dec 2011 18:22:00 +0000</pubDate><atom:updated>2011-12-22T21:52:03.786+03:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">News</category><title>خلاصه اشتراک‌های روز پنج شنبه 1 دي 1390</title><description>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;div dir='rtl' align='right'&gt;&lt;br/&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://tirania.org/blog/archive/2011/Dec-21.html' dir='ltr'&gt;Mono in 2011&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;tirania.org&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://www.harding.edu/fmccown/vbnet_csharp_comparison.html' dir='ltr'&gt;VB.NET and C# Comparison&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;www.harding.edu&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://wpfspark.codeplex.com/' dir='ltr'&gt;WPF Spark&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;wpfspark.codeplex.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://www.techrepublic.com/blog/10things/10-reasons-why-this-is-a-great-time-to-be-a-developer/2915' dir='rtl'&gt;الان وقت خوبی برای برنامه نویس شدن است!&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;www.techrepublic.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://blog.infochimps.com/2011/12/20/how-big-is-big-data/' dir='rtl'&gt;دیتای بزرگ چقدر بزرگه؟&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;blog.infochimps.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://michaelcrump.net/taking-a-look-at-the-windows-simulator-in-visual-studio-11' dir='rtl'&gt;نگاهی بر Windows Simulator نگارش بعدی ویژوال استودیو&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;michaelcrump.net&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7815821915651048578-5530092946537580267?l=www.dotnettips.info' alt='' /&gt;&lt;/div&gt;</description><link>http://www.dotnettips.info/2011/12/1-1390.html</link><author>noreply@blogger.com (وحيد نصيري)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7815821915651048578.post-2057855349209738050</guid><pubDate>Wed, 21 Dec 2011 18:09:00 +0000</pubDate><atom:updated>2011-12-21T21:39:25.320+03:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">News</category><title>خلاصه اشتراک‌های روز چهار شنبه 30 آذر 1390</title><description>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;div dir='rtl' align='right'&gt;&lt;br/&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://meyex.romanaco.com/1390/09/%d8%a7%d9%86%d8%aa%d8%ae%d8%a7%d8%a8-user-%d9%85%d9%86%d8%a7%d8%b3%d8%a8-%d8%a8%d8%b1%d8%a7%db%8c-service-%d9%87%d8%a7%db%8c-sql-server/' dir='rtl'&gt;انتخاب User مناسب برای Service های SQL Server&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;meyex.romanaco.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://blog.irscrum.com/?p=2584' dir='rtl'&gt;راهنمای مطلق اسکرام  به زبان فارسی&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;blog.irscrum.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://channel9.msdn.com/Events/ALM-Summit/2011/Unit-Testing-from-the-Trenches-Practical-Lessons-Practices' dir='ltr'&gt;Unit Testing Practical Lessons &amp;amp; Practices&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;channel9.msdn.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://www.codeproject.com/KB/cpp/LambdasCompared.aspx' dir='ltr'&gt;Using lambdas - C++ vs. C# vs. C++/CX vs. C++/CLI&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;www.codeproject.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://www.microsoft.com/download/en/details.aspx?id=28564' dir='ltr'&gt;Windows phone training&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;www.microsoft.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://blogs.jetbrains.com/dotnet/2011/12/christmas-is-here-resharper-61-dotcover-12-and-dottrace-452-released/' dir='rtl'&gt;ReSharper 6.1 منتشر شد&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;blogs.jetbrains.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://cyberrabbits.net/978/twitter-bootstrap/' dir='rtl'&gt;معرفی فریم ورک CSSایی به نام Twitter bootstrap&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;cyberrabbits.net&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://stackoverflow.com/questions/2422212/simple-c-sharp-csv-excel-export-class' dir='rtl'&gt;نکاتی که حین تهیه خروجی CSV سازگار با اکسل باید به آن‌ها دقت داشت&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;stackoverflow.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7815821915651048578-2057855349209738050?l=www.dotnettips.info' alt='' /&gt;&lt;/div&gt;</description><link>http://www.dotnettips.info/2011/12/30-1390.html</link><author>noreply@blogger.com (وحيد نصيري)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7815821915651048578.post-9072926024634255536</guid><pubDate>Wed, 21 Dec 2011 15:23:00 +0000</pubDate><atom:updated>2011-12-21T18:53:36.802+03:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">MVVM</category><title>MVVM و امكان استفاده از يك وهله از ViewModel جهت چند View مرتبط</title><description>&lt;div dir="rtl" style="text-align: right;" trbidi="on"&gt;&lt;br /&gt;
عموما هنگام طراحي يك View، خيلي زود به حجم انبوهي از كدهاي XAML خواهيم رسيد. در ادامه بررسي خواهيم كرد كه چطور مي‌توان يك View را به چندين View خرد كرد، بدون اينكه نيازي باشد تا از چندين ViewModel (يا همان code behind عاري از ارجاعات بصري سابق قرار گرفته در يك پروژه جداي ديگر) استفاده شود و تمام اين View هاي خرد شده هم تنها از يك وهله از ViewModel ايي خاص استفاده كنند و با اطلاعاتي يكپارچه سروكار داشته باشند؛ يا در عمل يكپارچه كار كنند. &lt;br /&gt;
اين مشكل از جايي شروع مي‌شود كه مثلا خرد كردن يك user control به چند يوزر كنترل، يعني كار كردن با چند وهله از اشيايي متفاوت. هر چند نهايتا تمام اين‌ها قرار است در يك صفحه در كنار هم قرار گيرند اما در عمل از هم كاملا مجزا هستند و اگر به ازاي هر كدام يكبار ViewModel را وهله سازي كنيم، به مشكل برخواهيم خورد؛ چون هر وهله نسبت به وهله‌اي ديگر ايزوله است. اگر در يكي Name مثلا Test بود در ديگري ممكن است مقدار پيش فرض نال را داشته باشد؛ چون با چند وهله از يك كلاس، در يك فرم نهايي سروكار خواهيم داشت.&lt;br /&gt;
&lt;br /&gt;
ابتدا Model و ViewModel ساده زير را در نظر بگيريد:&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="CSharp" name="code"&gt;using System.ComponentModel;

namespace SplittingViewsInMvvm.Models
{
    public class GuiModel : INotifyPropertyChanged
    {
        string _name;
        public string Name
        {
            get { return _name; }
            set
            {
                _name = value;
                raisePropertyChanged("Name");
            }
        }

        string _lastName;
        public string LastName
        {
            get { return _lastName; }
            set
            {
                _lastName = value;
                raisePropertyChanged("LastName");
            }
        }

        #region INotifyPropertyChanged Members
        public event PropertyChangedEventHandler PropertyChanged;
        void raisePropertyChanged(string propertyName)
        {
            var handler = PropertyChanged;
            if (handler == null) return;
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion
    }
}
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="CSharp" name="code"&gt;using SplittingViewsInMvvm.Models;

namespace SplittingViewsInMvvm.ViewModels
{
    public class MainViewModel
    {
        public GuiModel GuiModelData { set; get; }

        public MainViewModel()
        {
            GuiModelData = new GuiModel();
            GuiModelData.Name = "Name";
            GuiModelData.LastName = "LastName";
        }
    }
}
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
سپس View زير هم از اين اطلاعات استفاده خواهد كرد:&lt;br /&gt;
&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="XML" name="code"&gt;&amp;lt;UserControl x:Class="SplittingViewsInMvvm.Views.Main"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             xmlns:VM="clr-namespace:SplittingViewsInMvvm.ViewModels"
             d:DesignHeight="300" d:DesignWidth="300"&amp;gt;
    &amp;lt;UserControl.Resources&amp;gt;
        &amp;lt;VM:MainViewModel x:Key="vmMainViewModel" /&amp;gt;
    &amp;lt;/UserControl.Resources&amp;gt;
    &amp;lt;StackPanel DataContext="{Binding Source={StaticResource vmMainViewModel}}"&amp;gt;
        &amp;lt;GroupBox Margin="2" Header="Group 1"&amp;gt;
            &amp;lt;TextBlock Text="{Binding GuiModelData.Name}" /&amp;gt;
        &amp;lt;/GroupBox&amp;gt;
        &amp;lt;GroupBox Margin="2" Header="Group 2"&amp;gt;
            &amp;lt;TextBlock Text="{Binding GuiModelData.LastName}" /&amp;gt;
        &amp;lt;/GroupBox&amp;gt;
    &amp;lt;/StackPanel&amp;gt;
&amp;lt;/UserControl&amp;gt;
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
اكنون فرض كنيد كه مي‌خواهيم Group 1 و Group 2 را جهت مديريت ساده‌تر View اصلي در دو user control مجزا قرار دهيم؛ مثلا:&lt;br /&gt;
&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="XML" name="code"&gt;&amp;lt;UserControl x:Class="SplittingViewsInMvvm.Views.Group1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300"&amp;gt;
    &amp;lt;Grid&amp;gt;
        &amp;lt;GroupBox Margin="2" Header="Group 1"&amp;gt;
            &amp;lt;TextBlock Text="{Binding GuiModelData.Name}" /&amp;gt;
        &amp;lt;/GroupBox&amp;gt;
    &amp;lt;/Grid&amp;gt;
&amp;lt;/UserControl&amp;gt;
&lt;/pre&gt;&lt;/div&gt;و&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="XML" name="code"&gt;&amp;lt;UserControl x:Class="SplittingViewsInMvvm.Views.Group2"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300"&amp;gt;
    &amp;lt;Grid&amp;gt;
        &amp;lt;GroupBox Margin="2" Header="Group 2"&amp;gt;
            &amp;lt;TextBlock Text="{Binding GuiModelData.LastName}" /&amp;gt;
        &amp;lt;/GroupBox&amp;gt;
    &amp;lt;/Grid&amp;gt;
&amp;lt;/UserControl&amp;gt;
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
اكنون اگر اين دو را مجددا در همان View اصلي ساده شده قبلي قرار دهيم (بدون اينكه در هر user control به صورت جداگانه data context را تنظيم كنيم):&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="XML" name="code"&gt;&amp;lt;UserControl x:Class="SplittingViewsInMvvm.Views.Main"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             xmlns:V="clr-namespace:SplittingViewsInMvvm.Views"
             xmlns:VM="clr-namespace:SplittingViewsInMvvm.ViewModels"
             d:DesignHeight="300" d:DesignWidth="300"&amp;gt;
    &amp;lt;UserControl.Resources&amp;gt;
        &amp;lt;VM:MainViewModel x:Key="vmMainViewModel" /&amp;gt;
    &amp;lt;/UserControl.Resources&amp;gt;
    &amp;lt;StackPanel DataContext="{Binding Source={StaticResource vmMainViewModel}}"&amp;gt;
        &amp;lt;V:Group1 /&amp;gt;
        &amp;lt;V:Group2 /&amp;gt;
    &amp;lt;/StackPanel&amp;gt;
&amp;lt;/UserControl&amp;gt;
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
باز هم .... برنامه همانند سابق كار خواهد كرد و ViewModel وهله سازي شده در user control فوق به صورت يكساني در اختيار هر دو View اضافه شده قرار مي‌گيرد و نهايتا يك View يكپارچه را در زمان اجرا مي‌توان مورد استفاده قرار داد. علت هم بر مي‌گردد به مقدار دهي خودكار DataContext هر View اضافه شده به بالاترين DataContext موجود در Visual tree كه ذكر آن الزامي نيست: &lt;br /&gt;
&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="XML" name="code"&gt;&amp;lt;UserControl x:Class="SplittingViewsInMvvm.Views.Main"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             xmlns:V="clr-namespace:SplittingViewsInMvvm.Views"
             xmlns:VM="clr-namespace:SplittingViewsInMvvm.ViewModels"
             d:DesignHeight="300" d:DesignWidth="300"&amp;gt;
    &amp;lt;UserControl.Resources&amp;gt;
        &amp;lt;VM:MainViewModel x:Key="vmMainViewModel" /&amp;gt;
    &amp;lt;/UserControl.Resources&amp;gt;
    &amp;lt;StackPanel DataContext="{Binding Source={StaticResource vmMainViewModel}}"&amp;gt;
        &amp;lt;V:Group1 DataContext="{Binding}" /&amp;gt;
        &amp;lt;V:Group2 DataContext="{Binding}"/&amp;gt;
    &amp;lt;/StackPanel&amp;gt;
&amp;lt;/UserControl&amp;gt;
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
بنابراين به صورت خلاصه زمانيكه از MVVM استفاده ‌مي‌كنيد لازم نيست كار خاصي را جهت خرد كردن يك View به چند Sub View انجام دهيد! فقط اين‌ها را در چند User control جدا كنيد و بعد مجددا به كمك فضاي نامي كه تعريف خواهد (مثلا V در اينجا) در همان View اصلي تعريف كنيد. بدون هيچ تغيير خاصي باز هم برنامه همانند سابق كار خواهد كرد.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7815821915651048578-9072926024634255536?l=www.dotnettips.info' alt='' /&gt;&lt;/div&gt;</description><link>http://www.dotnettips.info/2011/12/mvvm-viewmodel-view.html</link><author>noreply@blogger.com (وحيد نصيري)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7815821915651048578.post-7746856958948757034</guid><pubDate>Tue, 20 Dec 2011 17:49:00 +0000</pubDate><atom:updated>2011-12-20T21:19:59.801+03:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">News</category><title>خلاصه اشتراک‌های روز سه شنبه 29 آذر 1390</title><description>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;div dir='rtl' align='right'&gt;&lt;br/&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://www.dotnetdev.info/2011/12/what-is-liskov-substitution-principle.html' dir='rtl'&gt;اصل Liskov Substitution چیست؟&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;www.dotnetdev.info&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://abugslife.ir/post/2011/12/19/rad-and-xp-methodologies.aspx' dir='rtl'&gt;متدولوژی‌های توسعه سریع نرم‌افزار&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;abugslife.ir&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://www.tirania.org/blog/archive/2011/Dec-19.html' dir='rtl'&gt;امکان استفاده مستقیم ازکلاس‌های سی++ در دات نت به کمک CXXI&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;www.tirania.org&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://blogs.msdn.com/b/ricom/archive/2011/12/19/performance-guidelines-for-properties.aspx' dir='rtl'&gt;بهبود کارآیی برنامه حین کار با خواص&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;blogs.msdn.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://www.red-gate.com/products/dotnet-development/ants-memory-profiler/learning-memory-management/memory-management-poster' dir='rtl'&gt;پوستر مدیریت حافظه در دات نت&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;www.red-gate.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://epplus.codeplex.com/discussions/208363' dir='rtl'&gt;مشکلات استفاده از مجوز GPL !&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;epplus.codeplex.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7815821915651048578-7746856958948757034?l=www.dotnettips.info' alt='' /&gt;&lt;/div&gt;</description><link>http://www.dotnettips.info/2011/12/29-1390.html</link><author>noreply@blogger.com (وحيد نصيري)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7815821915651048578.post-8759453017976290892</guid><pubDate>Mon, 19 Dec 2011 17:56:00 +0000</pubDate><atom:updated>2011-12-19T21:29:20.680+03:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">News</category><title>خلاصه اشتراک‌های روز دو شنبه 28 آذر 1390</title><description>&lt;div dir="rtl" style="text-align: right;" trbidi="on"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;div align="right" dir="rtl"&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a dir="rtl" href="http://blog.fardapardaz.com/post/2011/12/19/%D8%A7%D9%88%D9%84%DB%8C%D9%86-%D9%86%D8%B3%D8%AE%D9%87-%D9%86%D8%B1%D9%85-%D8%A7%D9%81%D8%B2%D8%A7%D8%B1-%D9%85%D9%88%D8%A8%D8%A7%DB%8C%D9%84%DB%8C-%D8%A7%D9%86%D8%AA%D8%AE%D8%A7%D8%A8-%D8%A7%D8%B3%D9%85.aspx"&gt;اولین نسخه نرم افزار موبایلی انتخاب اسم&lt;/a&gt; &lt;span style="color: darkgrey;"&gt;|&lt;/span&gt; &lt;span style="color: grey;"&gt;&lt;span dir="ltr"&gt;blog.fardapardaz.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a dir="ltr" href="http://blog.galasoft.ch/archive/2011/12/18/mvvm-light-installers-and-nuget-including-silverlight-5-mvvmlight.aspx"&gt;MVVM Light Nuget&lt;/a&gt; &lt;span style="color: darkgrey;"&gt;|&lt;/span&gt; &lt;span style="color: grey;"&gt;&lt;span dir="ltr"&gt;blog.galasoft.ch&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a dir="rtl" href="http://www.neowin.net/news/office-365-voted-best-cloud-app-of-2011"&gt;Office 365 به عنوان بهترین برنامه ابری سال 2011 انتخاب شد&lt;/a&gt; &lt;span style="color: darkgrey;"&gt;|&lt;/span&gt; &lt;span style="color: grey;"&gt;&lt;span dir="ltr"&gt;www.neowin.net&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a dir="rtl" href="http://www.misfitgeek.com/2011/12/choosing-a-css-framework/"&gt;انتخاب یک CSS Framework مناسب&lt;/a&gt; &lt;span style="color: darkgrey;"&gt;|&lt;/span&gt; &lt;span style="color: grey;"&gt;&lt;span dir="ltr"&gt;www.misfitgeek.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a dir="rtl" href="http://www.sqlservercurry.com/2011/12/why-is-raid-important-for-databases.html"&gt;اهمیت RAID حین کار با بانک‌های اطلاعاتی&lt;/a&gt; &lt;span style="color: darkgrey;"&gt;|&lt;/span&gt; &lt;span style="color: grey;"&gt;&lt;span dir="ltr"&gt;www.sqlservercurry.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a dir="rtl" href="http://geekswithblogs.net/dlussier/archive/2011/12/18/148070.aspx"&gt;چرا Phil Haack مایکروسافت را ترک کرد؟!&lt;/a&gt; &lt;span style="color: darkgrey;"&gt;|&lt;/span&gt; &lt;span style="color: grey;"&gt;&lt;span dir="ltr"&gt;geekswithblogs.net&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a dir="rtl" href="http://www.reddit.com/r/askscience/comments/ngv50/why_have_cpus_been_limited_in_frequency_to_around/"&gt;چرا چند سالی است که سرعت CPUها حدود 3.5Ghz باقی مانده؟&lt;/a&gt; &lt;span style="color: darkgrey;"&gt;|&lt;/span&gt; &lt;span style="color: grey;"&gt;&lt;span dir="ltr"&gt;www.reddit.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a dir="rtl" href="http://www.troyhunt.com/2011/12/free-ebook-owasp-top-10-for-net.html"&gt;کتاب رایگان OWASP Top 10 مخصوص برنامه نویس‌های دات نت&lt;/a&gt; &lt;span style="color: darkgrey;"&gt;|&lt;/span&gt; &lt;span style="color: grey;"&gt;&lt;span dir="ltr"&gt;www.troyhunt.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a dir="rtl" href="https://sourceforge.net/blog/25-fastest-growing-projects/"&gt;لیستی از 25 پروژه در حال رشد سورس فورج&lt;/a&gt; &lt;span style="color: darkgrey;"&gt;|&lt;/span&gt; &lt;span style="color: grey;"&gt;&lt;span dir="ltr"&gt;sourceforge.net&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a dir="rtl" href="http://zeeshanumardotnet.blogspot.com/2011/06/creating-reports-in-excel-2007-using.html"&gt;مثال‌هایی در مورد EPPlus&lt;/a&gt; &lt;span style="color: darkgrey;"&gt;|&lt;/span&gt; &lt;span style="color: grey;"&gt;&lt;span dir="ltr"&gt;zeeshanumardotnet.blogspot.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7815821915651048578-8759453017976290892?l=www.dotnettips.info' alt='' /&gt;&lt;/div&gt;</description><link>http://www.dotnettips.info/2011/12/28-1390.html</link><author>noreply@blogger.com (وحيد نصيري)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7815821915651048578.post-7405534034923721161</guid><pubDate>Sun, 18 Dec 2011 17:30:00 +0000</pubDate><atom:updated>2011-12-18T21:00:35.905+03:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">News</category><title>خلاصه اشتراک‌های روز يك شنبه 27 آذر 1390</title><description>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;div dir='rtl' align='right'&gt;&lt;br/&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://ootooban.com/1390/%db%b3%db%b3-%d8%b1%d8%a7%d9%87-%d8%a8%d8%b1%d8%a7%db%8c-%d8%ae%d9%84%d8%a7%d9%82-%d9%85%d8%a7%d9%86%d8%af%d9%86-%d8%a8%d9%88%d8%af%d9%86/' dir='rtl'&gt;۳۳ راه برای خلاق ماندن (بودن)! &lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;ootooban.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://blog.salarcode.com/2011/12/webp-future-of-web-image-formats.html' dir='rtl'&gt;WebP و آینده تصاویر وب&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;blog.salarcode.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://cssglobe.com/post/4175/pure-css-line-graph' dir='ltr'&gt;Pure Css Line Graph&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;cssglobe.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://www.irhoneynet.org/?p=97' dir='ltr'&gt;Windows 8 ROP&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;www.irhoneynet.org&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://weblogs.asp.net/dwahlin/archive/2009/04/06/5-reasons-you-should-take-a-closer-look-at-asp-net-mvc.aspx' dir='rtl'&gt;5 قابلیت جالب در ASP.NET MVC&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;weblogs.asp.net&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://highscalability.com/blog/2011/3/3/stack-overflow-architecture-update-now-at-95-million-page-vi.html' dir='rtl'&gt;مروری بر طراحی Stack Overflow&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;highscalability.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7815821915651048578-7405534034923721161?l=www.dotnettips.info' alt='' /&gt;&lt;/div&gt;</description><link>http://www.dotnettips.info/2011/12/27-1390.html</link><author>noreply@blogger.com (وحيد نصيري)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7815821915651048578.post-6439389086962776093</guid><pubDate>Sat, 17 Dec 2011 17:28:00 +0000</pubDate><atom:updated>2011-12-17T20:58:23.974+03:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">News</category><title>خلاصه اشتراک‌های روز شنبه 26 آذر 1390</title><description>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;div dir='rtl' align='right'&gt;&lt;br/&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://www.seomoz.ir/%d8%a8%d8%b1%d8%b1%d8%b3%db%8c-%da%a9%d8%af-%d9%87%d8%a7%db%8c-http.html' dir='rtl'&gt;بررسی کدهای HTTP &lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;www.seomoz.ir&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://blog.manipixel.com/1390/09/iran-web-festival-1390-advice/' dir='rtl'&gt;توصیه‌های یک داور جشنواره وب ایران&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;blog.manipixel.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://technopolis.ir/articles/webdesign/958_%d8%af%da%a9%d9%85%d9%87-%db%8c-%d9%85%d8%b3%d8%af%d9%88%d8%af-%d8%b4%d8%af%d9%87-%d9%84%d8%a7%db%8c%da%a9-%d9%81%db%8c%d8%b3%d8%a8%d9%88%da%a9-%d8%b1%d8%a7-%d8%a8%d9%87-%da%a9%d8%a7%d8%b1%d8%a8%d8%b1.html' dir='rtl'&gt;دکمه ی مسدود شده لایک فیسبوک را به کاربران ایرانی نشان ندهیم&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;technopolis.ir&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://www.30sharp.com/article/16/345/1/%d8%b3%d8%a7%d8%b2%da%af%d8%a7%d8%b1-%d9%86%d9%85%d9%88%d8%af%d9%86-data-contract-%d9%87%d8%a7-%d8%a8%d8%a7-%d9%86%d8%b3%d8%ae%d9%87-%d9%87%d8%a7%db%8c-%d8%a8%d8%b9%d8%af%db%8c.aspx' dir='rtl'&gt;سازگار نمودن Data Contract ها با نسخه های بعدی!&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;www.30sharp.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://www.nikamooz.com/index.php?option=com_content&amp;amp;view=article&amp;amp;id=129:-entity-framework-&amp;amp;catid=45:ef&amp;amp;Itemid=114' dir='rtl'&gt;مروری کلی بر قابلیت های موجود در Entity Framework-بخش اول&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;www.nikamooz.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://itsec.persianblog.ir/post/179' dir='rtl'&gt;مطالب منتخب هفته - امنیت اطلاعات&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;itsec.persianblog.ir&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://www.windowsphonegeek.com/news/new-free-e-book-windows-phone-toolkit-in-depth-2nd-edition' dir='ltr'&gt;FREE e-book: Windows Phone Toolkit In Depth&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;www.windowsphonegeek.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://lukencode.com/2011/12/11/netbashan-alternative-to-endless-admin-pages-in-asp-net-web-applications/' dir='ltr'&gt;NetBash&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;lukencode.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://googleplusrss.nodester.com/' dir='rtl'&gt;تهیه فید از مطالب عمومی ارسالی در گوگل پلاس&lt;/a&gt; &lt;span style='color:darkgray'&gt;|&lt;/span&gt; &lt;span style='color:gray'&gt;&lt;span dir='ltr'&gt;googleplusrss.nodester.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7815821915651048578-6439389086962776093?l=www.dotnettips.info' alt='' /&gt;&lt;/div&gt;</description><link>http://www.dotnettips.info/2011/12/26-1390.html</link><author>noreply@blogger.com (وحيد نصيري)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7815821915651048578.post-4760204352504029638</guid><pubDate>Sat, 17 Dec 2011 15:11:00 +0000</pubDate><atom:updated>2011-12-17T18:41:42.544+03:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">MVVM</category><title>استفاده از MVVM زمانيكه امكان Binding وجود ندارد</title><description>&lt;div dir="rtl" style="text-align: right;" trbidi="on"&gt;&lt;br /&gt;
ساده‌ترين تعريف MVVM، نهايت استفاده از امكانات Binding موجود در WPF و Silverlight است. اما خوب، هميشه همه چيز بر وفق مراد نيست. مثلا كنترل WebBrowser را در WPF در نظر بگيريد. فرض كنيد كه مي‌خواهيم خاصيت Source آن‌را در ViewModel مقدار دهي كنيم تا صفحه‌اي را نمايش دهد. بلافاصله با خطاي زير متوقف خواهيم شد:&lt;br /&gt;
&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="XML" name="code"&gt;A 'Binding' cannot be set on the 'Source' property of type 'WebBrowser'.
A 'Binding' can only be set on a DependencyProperty of a DependencyObject.
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
بله؛ اين خاصيت از نوع  DependencyProperty نيست و نمي‌توان چيزي را به آن Bind كرد. بنابراين اين نكته مهم را توسعه دهنده‌هاي كنترل‌هاي WPF و Silverlight هميشه بايد بخاطر داشته باشند كه اگر قرار است كنترل‌هاي شما MVVM friendly باشند بايد كمي بيشتر زحمت كشيده و بجاي تعريف خواص ساده دات نتي، خواص مورد نظر را از نوع DependencyProperty تعريف كنيد.&lt;br /&gt;
الان كه تعريف نشده چه بايد كرد؟&lt;br /&gt;
پاسخ متداول آن اين است: مهم نيست؛ خودمان مي‌توانيم اين‌كار را انجام دهيم! يك Attached property يا به عبارتي يك Behavior را تعريف و سپس به كمك آن عمليات Binding را ميسر خواهيم ساخت. براي مثال:&lt;br /&gt;
در اين Attached property قصد داريم يك خاصيت جديد به نام BindableSource را جهت كنترل WebBrowser تعريف كنيم:&lt;br /&gt;
&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="CSharp" name="code"&gt;using System;
using System.Windows;
using System.Windows.Controls;

namespace WebBrowserSample.Behaviors
{
    public static class WebBrowserBehaviors
    {
        public static readonly DependencyProperty BindableSourceProperty =
            DependencyProperty.RegisterAttached("BindableSource",
                            typeof(object),
                            typeof(WebBrowserBehaviors),
                            new UIPropertyMetadata(null, BindableSourcePropertyChanged));

        public static object GetBindableSource(DependencyObject obj)
        {
            return (string)obj.GetValue(BindableSourceProperty);
        }

        public static void SetBindableSource(DependencyObject obj, object value)
        {
            obj.SetValue(BindableSourceProperty, value);
        }

        public static void BindableSourcePropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            WebBrowser browser = o as WebBrowser;
            if (browser == null) return;

            Uri uri = null;

            if (e.NewValue is string)
            {
                var uriString = e.NewValue as string;
                uri = string.IsNullOrWhiteSpace(uriString) ? null : new Uri(uriString);
            }
            else if (e.NewValue is Uri)
            {
                uri = e.NewValue as Uri;
            }

            if (uri != null) browser.Source = uri;
        }
    }
}
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
يك مثال ساده از استفاده‌ي آن هم به صورت زير مي‌تواند باشد:&lt;br /&gt;
ابتدا ViewModel مرتبط با فرم برنامه را تهيه خواهيم كرد. اينجا چون يك خاصيت را قرار است Bind كنيم، همينجا داخل ViewModel آن‌را تعريف كرده‌ايم. اگر تعداد آن‌ها بيشتر بود بهتر است به يك كلاس مجزا مثلا GuiModel منتقل شوند.&lt;br /&gt;
&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="CSharp" name="code"&gt;using System;
using System.ComponentModel;

namespace WebBrowserSample.ViewModels
{
    public class MainWindowViewModel : INotifyPropertyChanged
    {
        Uri _sourceUri;
        public Uri SourceUri
        {
            get { return _sourceUri; }
            set
            {
                _sourceUri = value;
                raisePropertyChanged("SourceUri");
            }
        }

        public MainWindowViewModel()
        {
            SourceUri = new Uri(@"C:\path\arrow.png");
        }

        #region INotifyPropertyChanged Members
        public event PropertyChangedEventHandler PropertyChanged;
        void raisePropertyChanged(string propertyName)
        {
            var handler = PropertyChanged;
            if (handler == null) return;
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion
    }
}
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
در ادامه بجاي استفاده از خاصيت Source كه قابليت Binding ندارد، از Behavior سفارشي تعريف شده استفاده خواهيم كرد. ابتدا بايد فضاي نام آن تعريف شود، سپس BindableSource مرتبط آن در دسترس خواهد بود:&lt;br /&gt;
&lt;br /&gt;
&lt;div align="left" dir="ltr"&gt;&lt;pre language="XML" name="code"&gt;&amp;lt;Window x:Class="WebBrowserSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:VM="clr-namespace:WebBrowserSample.ViewModels"
        xmlns:B="clr-namespace:WebBrowserSample.Behaviors"
        Title="MainWindow" Height="350" Width="525"&amp;gt;
    &amp;lt;Window.Resources&amp;gt;
        &amp;lt;VM:MainWindowViewModel x:Key="vmMainWindowViewModel" /&amp;gt;
    &amp;lt;/Window.Resources&amp;gt;
    &amp;lt;Grid DataContext="{Binding Source={StaticResource vmMainWindowViewModel}}"&amp;gt;
        &amp;lt;WebBrowser B:WebBrowserBehaviors.BindableSource="{Binding SourceUri}" /&amp;gt;
    &amp;lt;/Grid&amp;gt;
&amp;lt;/Window&amp;gt;
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
نمونه مشابه اين مورد را در مثال «&lt;a href="http://www.dotnettips.info/2011/11/active-x-wpf.html"&gt;استفاده از كنترل‌هاي Active-X در WPF&lt;/a&gt;» پيشتر در اين سايت ديده‌ايد.&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7815821915651048578-4760204352504029638?l=www.dotnettips.info' alt='' /&gt;&lt;/div&gt;</description><link>http://www.dotnettips.info/2011/12/mvvm-binding.html</link><author>noreply@blogger.com (وحيد نصيري)</author><thr:total>10</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7815821915651048578.post-5486055562472339063</guid><pubDate>Fri, 16 Dec 2011 17:22:00 +0000</pubDate><atom:updated>2011-12-16T20:56:27.813+03:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">News</category><title>خلاصه اشتراک‌های روز جمعه 25 آذر 1390</title><description>&lt;div dir="rtl" style="text-align: right;" trbidi="on"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;div align="right" dir="rtl"&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a dir="rtl" href="http://www.nikamooz.com/index.php?option=com_content&amp;amp;view=article&amp;amp;id=128:entity-framework-ef-&amp;amp;catid=45:ef&amp;amp;Itemid=114"&gt;Entity Framework یا EF چیست؟&lt;/a&gt; &lt;span style="color: darkgrey;"&gt;|&lt;/span&gt; &lt;span style="color: grey;"&gt;&lt;span dir="ltr"&gt;www.nikamooz.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a dir="rtl" href="http://www.khorramirad.com/index.php?id=757"&gt;انتشار رایگان کتاب راهنمای ساختار شکست کار&lt;/a&gt; &lt;span style="color: darkgrey;"&gt;|&lt;/span&gt; &lt;span style="color: grey;"&gt;&lt;span dir="ltr"&gt;www.khorramirad.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a dir="rtl" href="http://www.30sharp.com/article/2/344/1/%d8%ae%d9%88%d8%a7%d9%86%d8%af%d9%86-%d9%81%db%8c%d8%af-%d9%87%d8%a7%db%8c-rss-%d8%a7%d8%b2-%d9%85%d9%86%d8%a7%d8%a8%d8%b9-%d9%85%d8%ae%d8%aa%d9%84%d9%81-%d9%88-%d8%a7%d9%86%d8%aa%d8%b4%d8%a7%d8%b1-%d9%85%d8%ac%d9%85%d9%88%d8%b9-%d8%a2%d9%86-%d9%87%d8%a7-%d8%a8%d8%a7-%d9%81%d8%b1%d9%85%d8%aa-rss.aspx"&gt;خواندن فید های RSS از منابع مختلف و انتشار مجموع آن ها با فرمت RSS&lt;/a&gt; &lt;span style="color: darkgrey;"&gt;|&lt;/span&gt; &lt;span style="color: grey;"&gt;&lt;span dir="ltr"&gt;www.30sharp.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a dir="rtl" href="http://somamos.blogfa.com/post-495.aspx"&gt;سماموس -  TV Series on Computing&lt;/a&gt; &lt;span style="color: darkgrey;"&gt;|&lt;/span&gt; &lt;span style="color: grey;"&gt;&lt;span dir="ltr"&gt;somamos.blogfa.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a dir="rtl" href="http://navid.kashani.ir/141/web-design-trends-in-2012/"&gt;گرایش‌های طراحی وب سایت در سال 2012&lt;/a&gt; &lt;span style="color: darkgrey;"&gt;|&lt;/span&gt; &lt;span style="color: grey;"&gt;&lt;span dir="ltr"&gt;navid.kashani.ir&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a dir="ltr" href="http://blog.pinboard.in/2011/12/don_t_be_a_free_user/"&gt;Don't Be A Free User&lt;/a&gt; &lt;span style="color: darkgrey;"&gt;|&lt;/span&gt; &lt;span style="color: grey;"&gt;&lt;span dir="ltr"&gt;blog.pinboard.in&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a dir="ltr" href="http://www.microsoft.com/download/en/details.aspx?id=27747"&gt;Download: MSDN/TechNet Forum Assistant&lt;/a&gt; &lt;span style="color: darkgrey;"&gt;|&lt;/span&gt; &lt;span style="color: grey;"&gt;&lt;span dir="ltr"&gt;www.microsoft.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a dir="ltr" href="http://lowagie.com/node/260"&gt;iText is free, not gratis&lt;/a&gt; &lt;span style="color: darkgrey;"&gt;|&lt;/span&gt; &lt;span style="color: grey;"&gt;&lt;span dir="ltr"&gt;lowagie.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a dir="ltr" href="http://dimecasts.net/Casts/ByTag/SOLID%20Principle"&gt;SOLID Casts&lt;/a&gt; &lt;span style="color: darkgrey;"&gt;|&lt;/span&gt; &lt;span style="color: grey;"&gt;&lt;span dir="ltr"&gt;dimecasts.net&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a dir="ltr" href="http://blogs.msdn.com/b/gusperez/archive/2005/08/09/449363.aspx"&gt;Static fields in generic classes&lt;/a&gt; &lt;span style="color: darkgrey;"&gt;|&lt;/span&gt; &lt;span style="color: grey;"&gt;&lt;span dir="ltr"&gt;blogs.msdn.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a dir="rtl" href="http://blogs.msdn.com/b/somasegar/archive/2011/12/15/visual-studio-11-platform-tooling-advances.aspx"&gt;بهبود امکانات جهت کار با دایرکت ایکس در ویژوال استودیوی بعدی&lt;/a&gt; &lt;span style="color: darkgrey;"&gt;|&lt;/span&gt; &lt;span style="color: grey;"&gt;&lt;span dir="ltr"&gt;blogs.msdn.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a dir="rtl" href="https://dotnettipsrepository.svn.codeplex.com/svn/Trunk/DotNetTipsCHM/"&gt;دریافت آخرین به روز رسانی فایل OPML وبلاگ‌های IT ایرانی&lt;/a&gt; &lt;span style="color: darkgrey;"&gt;|&lt;/span&gt; &lt;span style="color: grey;"&gt;&lt;span dir="ltr"&gt;dotnettipsrepository.svn.codeplex.com&lt;/span&gt;&lt;/span&gt; &lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7815821915651048578-5486055562472339063?l=www.dotnettips.info' alt='' /&gt;&lt;/div&gt;</description><link>http://www.dotnettips.info/2011/12/25-1390.html</link><author>noreply@blogger.com (وحيد نصيري)</author><thr:total>0</thr:total></item></channel></rss>

