به دلیل قابلیتهای binding پیشرفتهی WPF و Silverlight، الگوی MVVM بیشتر با این دو فناوری سازگار است؛ هر چند محدودیتی هم برای استفاده از آن در سایر حالات نیست.
نظرات مطالب
using System;
namespace SLAsyncTest.Helper
{
public interface IResult
{
void Execute();
event EventHandler Completed;
}
}
using System;
using System.Collections.Generic;
namespace SLAsyncTest.Helper
{
public class ResultEnumerator
{
private readonly IEnumerator<IResult> _enumerator;
public ResultEnumerator(IEnumerable<IResult> children)
{
_enumerator = children.GetEnumerator();
}
public void Enumerate()
{
childCompleted(null, EventArgs.Empty);
}
private void childCompleted(object sender, EventArgs args)
{
var previous = sender as IResult;
if (previous != null)
previous.Completed -= childCompleted;
if (!_enumerator.MoveNext())
return;
var next = _enumerator.Current;
next.Completed += childCompleted;
next.Execute();
}
}
}
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.Threading;
namespace SLAsyncTest.Web
{
[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode
= AspNetCompatibilityRequirementsMode.Allowed)]
public class TestService
{
[OperationContract]
public int GetNumber(int number)
{
Thread.Sleep(2000);//Simulating a log running operation
return number * 2;
}
}
}
using System;
using SLAsyncTest.Helper;
namespace SLAsyncTest.Model
{
public class GetNumber : IResult
{
public int Result { set; get; }
public bool HasError { set; get; }
private int _num;
public GetNumber(int num)
{
_num = num;
}
#region IResult Members
public void Execute()
{
var srv = new TestServiceReference.TestServiceClient();
srv.GetNumberCompleted += (sender, e) =>
{
if (e.Error == null)
Result = e.Result;
else
HasError = true;
Completed(this, EventArgs.Empty); //run the next IResult
};
srv.GetNumberAsync(_num);
}
public event EventHandler Completed;
#endregion
}
}
private void doFetch(object obj)
{
new ResultEnumerator(executeAsyncOps()).Enumerate();
}
private IEnumerable<IResult> executeAsyncOps()
{
FinalResult = 0;
IsBusy = true; //Show BusyIndicator
//Sequential Async Operations
var asyncOp1 = new GetNumber(10);
yield return asyncOp1;
//using the result of the previous step
if(asyncOp1.HasError)
{
IsBusy = false; //Hide BusyIndicator
yield break;
}
var asyncOp2 = new GetNumber(asyncOp1.Result);
yield return asyncOp2;
FinalResult = asyncOp2.Result; //Bind it to the UI
IsBusy = false; //Hide BusyIndicator
}
public class User { public int UserId {get;set;} public string Name {get;set;} public string Family {get;set;} public string Web {get;set;} public string Email {get;set;} public DateTime RegisterDate {get;set;} }
public class UserInfoViewModel { public string Name {get;set;} public string Family {get;set;} public string Email {get;set;} }
public UserInfoViewModel GetMemberByUserName(string username) { var result = from u in _users where u.UserName == username select new UserInfoViewModel() {Name = u.Name,Family=u.Family,Email=u.Email}; return result; }
<Window x:Class="WpfFontTest.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">
<Grid>
<TextBlock
Text="نمایش مخلوطی از متن فارسی و متن English با هم"
Margin="7"
FontFamily="Fonts/BNazanin.ttf#B Nazanin, Comic Sans Ms"
FontSize="25"
FlowDirection="RightToLeft"
VerticalAlignment="Top" HorizontalAlignment="Center" />
</Grid>
</Window>
using System.Collections.Generic; using System.IO; using Lucene.Net.Analysis.Standard; using Lucene.Net.Documents; using Lucene.Net.Index; using Lucene.Net.Store; using LuceneSearch.Core.Model; using LuceneSearch.Core.Utils; namespace LuceneSearch.Core { public static class CreateIndex { static readonly Lucene.Net.Util.Version _version = Lucene.Net.Util.Version.LUCENE_30; public static Document MapPostToDocument(Post post) { var postDocument = new Document(); postDocument.Add(new Field("Id", post.Id.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED)); var titleField = new Field("Title", post.Title, Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS); titleField.Boost = 3; postDocument.Add(titleField); postDocument.Add(new Field("Body", post.Body.RemoveHtmlTags(), Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS)); return postDocument; } public static void CreateFullTextIndex(IEnumerable<Post> dataList, string path) { var directory = FSDirectory.Open(new DirectoryInfo(path)); var analyzer = new StandardAnalyzer(_version); using (var writer = new IndexWriter(directory, analyzer, create: true, mfl: IndexWriter.MaxFieldLength.UNLIMITED)) { foreach (var post in dataList) { writer.AddDocument(MapPostToDocument(post)); } writer.Optimize(); writer.Commit(); writer.Close(); directory.Close(); } } } }
namespace LuceneSearch.Core.Model { public class SearchResult { public int Id { set; get; } public string Title { set; get; } } }
using System.Collections.Generic; using System.IO; using Lucene.Net.Index; using Lucene.Net.Search; using Lucene.Net.Store; using LuceneSearch.Core.Model; using LuceneSearch.Core.Utils; namespace LuceneSearch.Core { public static class AutoComplete { private static IndexSearcher _searcher; /// <summary> /// Get terms starting with the given prefix /// </summary> /// <param name="prefix"></param> /// <param name="maxItems"></param> /// <returns></returns> public static IList<SearchResult> GetTermsScored(string indexPath, string prefix, int maxItems = 10) { if (_searcher == null) _searcher = new IndexSearcher(FSDirectory.Open(new DirectoryInfo(indexPath)), true); var resultsList = new List<SearchResult>(); if (string.IsNullOrWhiteSpace(prefix)) return resultsList; prefix = prefix.ApplyCorrectYeKe(); var results = _searcher.Search(new PrefixQuery(new Term("Title", prefix)), null, maxItems); if (results.TotalHits == 0) { results = _searcher.Search(new PrefixQuery(new Term("Body", prefix)), null, maxItems); } foreach (var doc in results.ScoreDocs) { resultsList.Add(new SearchResult { Title = _searcher.Doc(doc.Doc).Get("Title"), Id = int.Parse(_searcher.Doc(doc.Doc).Get("Id")) }); } return resultsList; } } }
using System.Text; using System.Web.Mvc; using LuceneSearch.Core; using System.Web; namespace LuceneSearch.Controllers { public class HomeController : Controller { static string _indexPath = HttpRuntime.AppDomainAppPath + @"App_Data\idx"; public ActionResult Index(int? id) { if (id.HasValue) { //todo: do something } return View(); //Show the page } public virtual ActionResult ScoredTerms(string q) { if (string.IsNullOrWhiteSpace(q)) return Content(string.Empty); var result = new StringBuilder(); var items = AutoComplete.GetTermsScored(_indexPath, q); foreach (var item in items) { var postUrl = this.Url.Action(actionName: "Index", controllerName: "Home", routeValues: new { id = item.Id }, protocol: "http"); result.AppendLine(item.Title + "|" + postUrl); } return Content(result.ToString()); } } }
@{ ViewBag.Title = "جستجو"; var scoredTermsUrl = Url.Action(actionName: "ScoredTerms", controllerName: "Home"); var bulletImage = Url.Content("~/Content/Images/bullet_shape.png"); } <h2> جستجو</h2> <div align="center"> @Html.TextBox("term", "", htmlAttributes: new { dir = "ltr" }) <br /> جهت آزمایش lu را وارد نمائید </div> @section scripts { <script type="text/javascript"> EnableSearchAutocomplete('@scoredTermsUrl', '@bulletImage'); </script> }
function EnableSearchAutocomplete(url, img) { var formatItem = function (row) { if (!row) return ""; return "<img src='" + img + "' /> " + row[0]; } $(document).ready(function () { $("#term").autocomplete(url, { dir: 'rtl', minChars: 2, delay: 5, mustMatch: false, max: 20, autoFill: false, matchContains: false, scroll: false, width: 300, formatItem: formatItem }).result(function (evt, row, formatted) { if (!row) return; window.location = row[1]; }); }); }
result.AppendLine(item.Title + "|" + postUrl); return Content(result.ToString());
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="LuceneSearch.WebForms.Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width" /> <title>جستجو</title> <link href="Content/Site.css" rel="stylesheet" type="text/css" /> <script src="Scripts/jquery-1.7.1.min.js" type="text/javascript"></script> <script src="Scripts/jquery.autocomplete.js" type="text/javascript"></script> <script src="Scripts/custom.js" type="text/javascript"></script> </head> <body dir="rtl"> <h2> جستجو</h2> <form id="form1" runat="server"> <div align="center"> <asp:TextBox runat="server" dir="ltr" ID="term"></asp:TextBox> <br /> جهت آزمایش lu را وارد نمائید </div> </form> <script type="text/javascript"> EnableSearchAutocomplete('Search.ashx', 'Content/Images/bullet_shape.png'); </script> </body> </html>
using System.Text; using System.Web; using LuceneSearch.Core; namespace LuceneSearch.WebForms { public class Search : IHttpHandler { static string _indexPath = HttpRuntime.AppDomainAppPath + @"App_Data\idx"; public void ProcessRequest(HttpContext context) { string q = context.Request.QueryString["q"]; if (string.IsNullOrWhiteSpace(q)) { context.Response.Write(string.Empty); context.Response.End(); } var result = new StringBuilder(); var items = AutoComplete.GetTermsScored(_indexPath, q); foreach (var item in items) { var postUrl = "Default.aspx?id=" + item.Id; result.AppendLine(item.Title + "|" + postUrl); } context.Response.ContentType = "text/plain"; context.Response.Write(result.ToString()); context.Response.End(); } public bool IsReusable { get { return false; } } } }
result.AppendLine(item.Title + "|" + postUrl); context.Response.Write(result.ToString());
public IActionResult Create([FromBody] CreateViewModel vm) {
[ModelBinder(BinderType = typeof(PersianDateModelBinder))] public partial class CreateViewModel { public int Id { get; set; } [DisplayName("عنوان مطلب")] public string Title { get; set; } [DisplayName("نگارش مطلب")] public string Content { get; set; } [DisplayName("تاریخ درج")] public DateTime CreateDate { get; set; } = DateTime.Now.Date; [DisplayName("تاریخ انتشار")] public DateTime PublishDate { get; set; } = DateTime.Now.Date; }
namespace Refactoring.Day1.EncapsulateCollection
{
public class OrderItem
{
public int Id { set; get; }
public string Name { set; get; }
public int Amount { set; get; }
}
}
using System.Collections.Generic;
namespace Refactoring.Day1.EncapsulateCollection
{
public class Orders
{
public List<OrderItem> OrderItems { set; get; }
}
}
Error, Certainty 95, for Do Not Expose Generic Lists
Warning, Certainty 75, for Collection Properties Should Be ReadOnly
using System.Linq;
using System.Collections.Generic;
namespace Refactoring.Day1.EncapsulateCollection
{
public class Orders
{
private int _orderTotal;
private List<OrderItem> _orderItems;
public IEnumerable<OrderItem> OrderItems
{
get { return _orderItems; }
}
public void AddOrderItem(OrderItem orderItem)
{
_orderTotal += orderItem.Amount;
_orderItems.Add(orderItem);
}
public void RemoveOrderItem(OrderItem orderItem)
{
var order = _orderItems.Find(o => o == orderItem);
if (order == null) return;
_orderTotal -= orderItem.Amount;
_orderItems.Remove(orderItem);
}
}
}
<InputText @bind-Value="employee.FirstName" />
[Parameter] public string Value { set; get; }
[Parameter] public EventCallback<string> ValueChanged { get; set; }
[Parameter] public Action<string> ValueChanged { get; set; }
[Parameter] public Expression<Func<string>> ValueExpression { get; set; }
private string _value; [Parameter] public string Value { get => _value; set { var hasChanged = string.Equals(_value, value, StringComparison.Ordinal); if (hasChanged) { _value = value; if (ValueChanged.HasDelegate) { _ = ValueChanged.InvokeAsync(value); } } } }