DCSIMG
April 2010 - Posts - שלמה גולדברג (הרב דוטנט)

שלמה גולדברג (הרב דוטנט)

מרצה בסלע ויועץ בעולם ה - net.

April 2010 - Posts

Error: Type [Ajax Object] has already been registered

פתרון להודעת שגיאה מהסוג הזה:

 

Sys.InvalidOperationException: Type [Ajax Object] has already been registered. The type may be defined multiple times or the script file that defines it may have already been loaded. A possible cause is a change of settings during a partial update



תיאור הבעייה:
במקרים מסויימים (מייד אתאר את המקרה הספציפי שלי) כשמציבים אובייקט כלשהו של AJAX בתוך Update Panel נקבל הודעת שגיאה מהסוג הזה.
במקרה שלי השתמשתי עם Rating של AjaxControlTollkit ועטפתי אותו עם RadAjaxPanel של טלריק, ובכל פעם שניסיתי לעשות Post Back מתוך הפאנל קבלתי את הודעת השגיאה הזאת.


פיתרון הבעייה:
אחרי קצת שוטטות בגוגל הגעתי לכאן מתואר שם בעייה דומה עם Timer של AJAX.
ההצעה שם הייתה להגדיר את המאפיין - ScriptMode של ה - ScriptManager ל - Release.

מסתבר שזה אכן הפיתרון הנכון, לא חקרתי את הסיבות למה ב - Debug Mode הם מנסים לרשום כמה פעמים את אותו סקריפט
אבל כל עוד שזה עובד זה בסדר מבחינתי.

Delete object in Entity Framework

 

אם תנסו למחוק אובייקט ב - collection ב - entity framework בעזרת remove בצורה הבאה
 

Lecture lecture = entities.Lectures.Include("SelaRelatedCourses").First();

lecture.SelaRelatedCourses.Remove(lecture.SelaRelatedCourses.ElementAt(0));

 
אתם יכולים לקבל הודעת שגיאה בהסגנון הזה
 
A relationship is being added or deleted from an AssociationSet 'FK_Relatedcourses_Lecture'. With cardinality constraints, a corresponding 'SelaRelatedCourses' must also be added or deleted.
 
 
כדי למחוק בצורה נכונה עדיף לכתוב ככה
 

entities.DeleteObject(lecture.SelaRelatedCourses.ElementAt(0));

The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>)

 

אני מניח שכבר נתקלתם בהודעה המעצבנת הזאת - בדרך כלל מקבלים את ההודעה כשיש לנו סקריפט שכזה
 

btnUpdateId = '<%= btnUpdateCreate.ClientID %>';

imgLectId = '<%= imgLect.ClientID %>';

cvEmailUniqeId = '<%= cvEmailUniqe.ClientID %>';

 
לא ברור לי מתי מקבלים את ההודעה הזאת - כלומר מה צריך לעשות כדי לדפוק את הקוד כדי שזה יקרה, אבל הפיתרון הוא די פשוט.
 
פשוט תעטפו את הקוד עם div שהוגדר כ - runat=server
 
 

<div runat="server">

 

    <script type="text/javascript">

        btnUpdateId = '<%= btnUpdateCreate.ClientID %>';

        imgLectId = '<%= imgLect.ClientID %>';

        cvEmailUniqeId = '<%= cvEmailUniqe.ClientID %>';

    </script>

 

</div>

Unable to update the EntitySet '[TableName]' because it has a DefiningQuery and no <InsertFunction> element exists in the <ModificationFunctionMapping> element to support the current operation

 

היה לי בבסיס הנתונים קישור פשוט של רבים לרבים
many to many
 
 
מבחינת האובייקטים ב - Entity Framework זה נוצר בצורה הזאת
 
EF - many to many
 
 
הקשר בין הרצאה לתגים הוא רבים לרבים. כשניסיתי לכתוב את הקוד הזה
 
 

Lecture lecture = entities.Lectures.First();

Tag tag = new Tag() { Name = "acbd" };

lecture.Tags.Add(tag);

 

entities.SaveChanges();

 
קבלתי את ההודעה הבאה
 
 
Unable to update the EntitySet 'TagLecture' because it has a DefiningQuery and no <InsertFunction> element exists in the <ModificationFunctionMapping> element to support the current operation
 
 
התחלתי לחקור את הנושא ופתחתי את קובץ ה - xml שה - EF מייצר.
 
וראיתי את ההודעה הבאה
 
 <!--Errors Found During Generation:
      warning 6002: The table/view 'SCO.dbo.TagLecture' does not have a primary key defined. The key has been inferred and the definition was created as a read-only table/view.
 
מסתבר שלא היה בטבלת הקשר TagLecture אף מפתח ראשי. הגדרתי את שני העמודות כמפתח ראשי רפרשתי את המודל והכול בא על מקומו בשלום

XMLHttpRequest vs. PostBack

 

זה נכון שכדי לעבוד עם AJAX אנחנו עובדים עם ספריות כמו של ScriptManager או של jQuery, אבל בכל זאת חשבתי לכתוב דוגמא לשימוש ב - XMLHttpRequest לבד.
 
את הדוגמא אפשר להוריד מכאן.
 
נניח שיש לנו מסך שנראה כך:
ajax
 
המשתמש יבחר שם -
במידה והוא לוחץ על הלחצן server אנחנו ניגש לשרת בצורה רגילה (כלומר PostBack) ונביא נתונים אודות המשתמש.
במידה והוא לוחץ על הלחצן xml אנחנו ניגש לשרת בעזרת XMLHttpRequest ונביא את הנתונים.
 
 
קוד ה - HTML
 

 

<div id='mydiv'></div>

 

<asp:ListBox ID="name" runat="server">

    <asp:ListItem>shlomo</asp:ListItem>

    <asp:ListItem>noam</asp:ListItem>

    <asp:ListItem>yossi</asp:ListItem>

</asp:ListBox>

 

<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Server" />

<input id="Button2" type="button" value="xml" onclick="GetHtml()" />

 
 
 
יש לנו handler שיודע להחזיר html לפי פרמטר בשם name - הנה הקוד שלו
 

public void ProcessRequest(HttpContext context)

{

    context.Response.ContentType = "text/plain";

    if (context.Request["name"] == "shlomo")

    {

        context.Response.Write("name=shlomo<br/>last name=goldberg<br/>age=25");

    }

    else if (context.Request["name"] == "noam")

    {

        context.Response.Write("name=noam<br/>last name=king<br/>age=40");

    }

    else if (context.Request["name"] == "yossi")

    {

        context.Response.Write("name=yossi<br/>last name=goldberg<br/>age=23");

    }

}

כמו שאתם שמים לב - לפי הפרמטר name ה - handler מייצר קוד html ומוסיף את זה ל - Response.
 
 
כעת נראה מה קורה כשהמשתמש ילחץ על הלחצן Server
 

protected void Button1_Click(object sender, EventArgs e)

{

    var x = new Data();

    x.ProcessRequest(HttpContext.Current);

}

 
אנחנו מייצרים מופע של ה - Handler (הוא נקרא Data) ומפעילים את מתודת ProcessRequest שכאמור תוסיף ל - Response את ה - html המתאים. (הפרמטר name נשלח ב - Request היות שה - Id של ה - ListBox הוא name)
 
כמובן שהלחיצה על הלחצן תעשה PostBack מלא - וכל הדף יתרפרש כדי לייבא את הנתונים.
 
כעת נראה מה יקרה אם נלחץ על ה - xml
 

function GetHtml() {

    var xhr = new XMLHttpRequest();

    var data = '?name=' + document.getElementById('name').value;

    var url = 'http://localhost:3319/Data.ashx' + data;

    xhr.open("GET", url, true);

 

    xhr.onreadystatechange = function() {

        if (xhr.readyState == 4) {

            document.getElementById('mydiv').innerHTML = xhr.responseText;

        }

    }

 

    xhr.send(null);

}

 
בשורה הראשונה אנחנו מייצרים מופע של XMLHttpRequest
 
לאחריו אנחנו מייצרים queryString שנראה כך:
?name=noam
כמובן שהוא לוקח את הערך מתוך מה שהמשתמש בחר.
 
נגדיר את ה - url ל - handler ונוסיף את ה - query string
 
נפתח connection ומגדיר שאנחנו שולחים ב - GET ל - url שהגדרנו ואנחנו רוצים לעשות את זה בצורה אסינכרונית (כלומר לא לחכות לתשובה)
 
נרשם לאירוע שנקרא onreadystatechange ונגדיר שאם ה - state הוא 4 (כלומר קבלנו תשובה) נכתוב ל - div את ה - html שקבלנו.
 
ונפעיל את הבקשה בעזרת קריאה ל - send.
 
 
כמובן שבשיטה הזאת אין PostBack והכל הרבה יותר מהיר וחסכנו בתעבורה.

Add functionality using Document Object Model Prototypes (IE8)

 

אחד מהיכלות החדשות שיש לנו ב - IE8 זה ההוספה של prototype ל - DOM.
 
אני לא אסביר בפוסט הזה מהו ה - prototype. אבל אם אתם לא מכירים את המושג (שקיים כבר הרבה לפני IE8) אני ממליץ לכם לקרוא את הפוסט הזה (לפחות את החלק הראשון) - או את הפוסט הזה - Object Oriented Programming in JavaScript
 
ב - IE8 הוסיפו ל - DOM את היכולת לשנות ולהוסיף פונקציות בעזרת prototype.
 
לדוגמא. אני מניח שהרבה פעמים יצא לכל אחד מכם לכתוב פונקציה שנקראת כך:
 

function HideFunc(obj) {

    obj.style.display = 'none';

}

 
ומן הסתם השתשמתם בפונקציה כדי להסתיר אלמנטים במסך.
 
 
שימו לב לקוד הבא:
 

function HideFunc() {

    this.style.display = 'none';

}

 

function ShowFunc() {

    this.style.display = 'block';

}

 

Element.prototype.Hide = HideFunc;

Element.prototype.Show = ShowFunc;

 

<input type="button" value="click to hide" onclick="this.Hide()" />

 
למעשה הוספנו את המתודות Hide ו - Show לכל האלמנטים של ה - DOM - (מאוד מזכיר extension Method)
 
לקרחאה מלאה אודות היכולות של prototype על ה - DOM תוכלו לקרוא כאן

Invoke PageMethods (ScriptManager) synchronously

 

בפוסט הזה התרעמתי על הצורה שמיקרוסופט מימשו את ה - PageMethods - כתבתי שהם כתבו harscode שכל הקריאות יהיו async.
 
כתוצאה מזה שאני חוקר כרגע את IE8 חקרתי קצת את הנושא של prototype ב - javascript מצאתי דרך לשנות ולהגדיר קריאות ב - PageMethods שיעכבו את המשך הריצה עד לקבלת תשובה.
 
 
לפני שאני אכתוב את הפיתרון נסתכל איך מיקרוסופט מימשו את ה - PageMethods. אם נחפור קצת בקובץ ה - javascript שמגיע עם ה - script manager נראה את הקוד הבא.
 

function Sys$Net$XMLHttpExecutor$executeRequest() {

    // some code...

 

    var verb = this._webRequest.get_httpVerb();

    this._xmlHttpRequest.open(verb, this._webRequest.getResolvedUrl(), true);

 

    // some code..

}

 
בכל פעם שנפעיל מתודה בעזרת ה - Script Manager נגיע למתודה הזאת שבו הם מפעילים את מתודת open שולחים האם זה GET או POST שולחים את הכתובת של המתודה ו - true כדי להגדיר שזה אסינכרוני.
 
כדי שנוכל להחליט האם אנחנו רוצים את ההפעלה בצורה סינכרונית (למשל ב - CustomValidator) נצטרך לכתוב את הקוד הבא.
 

XMLHttpRequest.prototype.base_open = XMLHttpRequest.prototype.open;

 

XMLHttpRequest.prototype.open = function(method, url, async, user, password) {

    async = false;

 

    var args = Array.prototype.slice.call(arguments);

    return this.base_open.apply(this, args);

};

 
 
בהתחלה נשמור reference למתודה open של XMLHttpRequest בעזרת prorotype.
 
לאחר מכן נגדיר מימוש חדש למתודה open (כלומר בכל פעם שיפעילו את המתודה open יגיעו למימוש שלנו)
 
נוכל להגדיר שהפרמטר async יהיה true או false.
 
ונפעיל את המימוש הקודם של open.
 
 
כעת נוכל לכתוב custom validator ולממש אותו בעזרת PageMethods  (ולא נצטרך להגיע ל - jQuery - כמו שכתבתי כאן)
 

<asp:Button ID="Button1" runat="server" Text="Button" />

<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>

<asp:CustomValidator

        ValidateEmptyText="true"

        ID="CustomValidator1"

        ControlToValidate="TextBox1"

        ClientValidationFunction="customValid"

        runat="server"

        ErrorMessage="CustomValidator">

</asp:CustomValidator>

 

 

function customValid(sender, args) {

    PageMethods.IsOk(args.Value, function(res) {

        args.IsValid = res;

    });

}

 

//Server Code

[WebMethod]

public static bool IsOk(string str)

{

    return str == "ok";

}

IE8 - DOM Storage

 

אני מכין חומר בימים אלו על Internet Explorer 8 - למעשה כבר התחלתי לכתוב על זה בעבר, וכעת אני מתכוון להמשיך.
 
בפוסט הנוכחי אני אדבר על אחד מהתכונות הטובות ביותר שיש ב - IE8. Dom Storage
 
מפתחי WEB יודעים שיש כמה דרכים לשמור מידע, חלק מהדרכים הם בצד הלקוח וחלק בצד השרת, בדרך כלל גם כששומרים מידע בצד הלקוח השרת מכיר את המידע, הדרך הוותיקה והנפוצה לשמור בצד הלקוח כמובן עוגיות, עוגיות הם הדרך הטובה ביותר לשמור מידע בצד הלקוח לאורך זמן.
 
כמובן שגם לעוגיות יש חסרונות, כשהחיסרון הגדול הוא שזה לא קל לגשת אל המידע שנשמר בעוגייה (צריך לשחק עם מחרוזות) וכמובן שכל העוגייות נשלחות לשרת בכל Request (בין אם צריך אותם ובין אם לא).
 
 
יש מקרים שבהם אתם יכולים לכתוב קוד לדפדפן מסויים - כמובן שאם אתם כותבים אתר לציבור הרחב (אתרי חדשות וכדו') אתם אמורים לתמוך בהרבה דפדפנים, אבל אם אתם כותבים אתר פנימי (אתר לשימוש עובדי משרד הפנים - לא האתר שמשמש את הציבור הרחב אלא האתר הפנימי של העובדים) אפשר בהחלט לדרוש שישתמשו בדפדפן מסויים. במקרה ואתם יודעים שישתמשו ב - IE8 מן הסתם לא תרצו יותר לשמור מידע בעוגייות (אלא במקרי קצה) ותעדיפו לעבוד אם ה - DOM Stroage - הוא הרבה יותר פשוט לעבודה, ניתן לשמור בו כמויות עצומות של מידע (ביחס לעוגיות) והוא לא נשלח לשרת בכל Request.
 
(דרך אגב למי שמכיר ה - DOM Storage הוא התחליף ל - UserData בגרסאות קודמות של IE)
 
השוואה בין DOM Storage לבין עוגיות
 
 
  Cookie DOM Storage
גודל מקסימלי 4KB (IE8 - 10KB) 10MB
מוכר בשרת נשלחים עם כל בקשה לא מוכר
הרשאות לפי דומיין ותיקייה לפי דומיין בלבד
גישה חיפוש על מחרוזות בעזרת אובייקטים ומתודות
אירועים אין בזמן שינוי והוספה ובזמן סיום הכתיבה
מחיקה לפי זמן ידנית או בזמן סגירת הדפדפן
סוג מידע מחרוזות מחרוזות מספרים וערכים בוליאניים
 
 
 
אז איך משתמשים בזה:
 
למעשה יש שני אובייקטים שונים - הראשון הוא sessionStorage והשני הוא localStorage. ההבדל היחיד ביניהם הוא שה - sessionStorage חי כל עוד שהטאב הנוכחי פתוח, לעומת ה - localStorage שחי כל עוד שלא מחקו אותו.
 
השימוש הוא ממש פשוט, לדוגמא:
 

<input type="checkbox" onchange="sessionStorage.insurance = this.checked">

 
בדוגמא הזאת יצרנו (אם לא היה קיים) משתנה בשם insurance  ב - sessionStorage וכעת אפשר בכל מקום לשאול
 

if (sessionStorage.insurance)

 
דוגמא נוספת (להצגת מספר הפעמים שמשתמש ביקר בדף מסוים)
 

<p>

  You have viewed this page <span id="count"> an untold number of</span>

  time(s).

</p>

<script>

    var storage = window.localStorage;

    if (!storage.pageLoadCount) {

        storage.pageLoadCount = 0;

    }

    storage.pageLoadCount = parseInt(storage.pageLoadCount, 10) + 1;

    document.getElementById('count').innerHTML = storage.pageLoadCount;

</script>

 
 
 
בנוסף לזה יש ל - storage מספר מתודות שימושיות - תוכלו לקרוא עליהם כאן 
מתודה מעניינת היא remainingSpace שמחזירה את גודל המקום הפנוי (בבתים).
 
בנוסף היכולת לרוץ בקלות בלולאה על כל הערכים בעזרת המתודה key ו - getItem
 

for (var i = 0; i < window.localStorage.length; i++) {

    var key = window.localStorage.key(i);

    var data = window.localStorage.getItem(key);

}

 
יש גם שני אירועים מעניינים שאפשר להירשם אליהם - onstorage כשמשהו משתנה ו - onstoragecommit כשה - localStorage סיים לשמור את עצמו בדיסק (קבצי xml)

Add Javascript file form code in user control

 

נניח שיש לכם User Control שמשתמש בפונקציות שנמצאות בקובץ javascript, צריך כמובן להוסיף הפנייה ב - html לקובץ ה - javascript.
 
השאלה - איפה לשים את ההפנייה, הכי קל כמובן זה לשים אותו בדף שמשתמש ב - User Control, הבעייה היא כמובן שנצטרך תמיד לזכור בכל דף שבו משתמשים עם ה - User Control להוסיף את ההפנייה לקובץ ה - javascript.
 
אופצייה שנייה היא להוסיף את ההפנייה בקובץ ה - ascx (כלומר ב - UserControl בעצמו) ואז בכל דף שיהיה בו את ה - User Control הוא יביא איתו את קובץ ה - javascript שזה הרבה יותר הגיוני.
 
אבל זה גורם לנו לבעייה, אם בדף יהיה יותר ממופע אחד של ה - User Control הלקוח ינסה להוריד פעמיים את קובץ ה - javascript (מכיוון שכל מופע מביא איתו ביחד את הפנייה לקובץ ה - javascript)
 
הפיתרון שמצאתי הוא - להוסיף את ההפנייה מקוד ולוודא שהוא לא קיים על הדף, נעשה את זה בעזרת הקוד הבא.
 

if (!Page.ClientScript.IsClientScriptIncludeRegistered("key"))

{

    string url = ResolveClientUrl("~/Scripts/file.js");

    Page.ClientScript.RegisterClientScriptInclude("key", url);

}

Movies - Validator Part 2

 

כמו שהבטחתי הנה הנמשך הסרטון על ולידציות ב - asp.net
 
בסרטון הנוכחי אני עושה היכרות עם פקדי הולידציות המובנים שקיימים
 
אפשר להוריד את זה מכאן או לצפות בבלוג
 
תהנו

Custom Validator with ajax call

 

נניח שיש לכם custom validator שאתם רוצים בצד הקליינט לפנות ב - ajax לשרת.
 
 
 

<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />

<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>

 

<asp:CustomValidator ID="CustomValidator1" ControlToValidate="TextBox1"

    ClientValidationFunction="customValid"

    runat="server" ErrorMessage="CustomValidator"></asp:CustomValidator>

 
 
המתודה להפעלה בזמן ולידצייה (הייתי שמח להשתמש עם ScriptManager אבל לצערי הם כתבו את הקוד שלהם בצורה מטופשת (קצת) שעושה את הקריאות תמיד בצורה אסינכרונית וחבל שהם לא נתנו את היכולת להחליט האם להריץ בצורה סינכרונית או אסינכרונית)
 
ולכן השתמשתי ב - jQuery
 

function customValid(sender, args) {

    $.ajax({

        type: 'POST',

        url: 'WebService1.asmx/IsOk',

        data: { str: args.Value },

        async: false,

        success: function(result) {

            args.IsValid = eval(result.text);

        }

    });

}

 
אני מפעיל את המתודה IsOk ב - WebService בצורה סינכרונית (אחרת יהיה לי PostBack עוד לפני שאני אקבל תשובה)
 
הנה המתודה ב - WebService
 

[WebMethod]

public bool IsOk(string str)

{

    return str == "ok";

}

Upload file (ftp) using c#

 

דוגמת קוד שכתב אחי יוסי גולדברג להעלאת קבצים ל - ftp
 

string url = "ftpUrl/FileName";

FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(url);

 

request.Method = WebRequestMethods.Ftp.UploadFile;

request.Credentials = new NetworkCredential("user name", "password");

request.UsePassive = true;

request.UseBinary = true;

request.KeepAlive = false;

 

 

byte[] buffer = File.ReadAllBytes("path");

 

using (Stream reqStream = request.GetRequestStream())

{

    reqStream.Write(buffer, 0, buffer.Length);

}

 
אם לא רוצים לקרוא את כל הקובץ בבת אחת אפשר כמובן לכתוב ככה
 

using (Stream reqStream = request.GetRequestStream())

{

    int count = 0;

    byte[] buffer = new byte[100];

    using (FileStream file = new FileStream("FileName", FileMode.Open))

    {

        while ((count = file.Read(buffer, 0, 100)) > 0)

        {

            reqStream.Write(buffer, 0, count);

        }

    }

 

}

Posted: Apr 11 2010, 07:47 PM by Shlomo | with 13 comment(s)
תגים:, , ,

הדרכים לפתיחת חלון חדש בצד הלקוח

 

יש כמה דרכים לפתוח חלונות ב - JavaScript ולכל דרך יש פיצ'רים משלה.
בפוסט הזה אני ארכז את הדרכים ואת התכונות לכל אחת מהם.
 
הנה הרשימה של כל הדרכים ולאחר מכן פירוט התחביר והתכונות של כל אחד מהם.
 
window.open()
window.navigate()
window.location.href
window.location.assign()
window.location.replace()
window.showModalDialog()
window.showModelessDialog()
 
window.open מקבל את הפרמטרים הבאים
 

var oNewWindow = window.open( [sURL] [, sName] [, sFeatures] [, bReplace]);

 

 
הפרמטר sUrl הינו כמובן את מי רוצים לפתוח - הוא אופציונלי ואם הוא לא יקבל ערך יפתח חלון שרואים בו "about:blank"
 
הפרמטר sName יכול לקבל את השם של החלון (מקביל ל - target של לינק) מה שחשוב זה blank_ שזה ברירת המחדל מה שאומר שזה יפתח בחלון חדש, self_ שאומר שיפתח בחלון הנוכחי, לשאר האופציות אפשר לעיין בלינק לעיל (על window.open).
 
הפרמטר sFeatures מקבל רשימה של ערכים שקובעים איך יראה החלון (גודל, מסך מלא, מיקום, ועוד) לרשימה המלאה ניתן לעיין בלינק.
 
הפרמטר bReplace מקבל ערך true אם נרצה שהחלון החדש יתווסף לרשימת ההיסטורייה בדפדפן (כמובן שרק עם החלון נפתח בדף הנוכחי יש משמעות להגדיר true).
 
 
window.navigate מקבל את הפרמטר הבא
 

window.navigate(sUrl);

מקבל את השם של הדף פותח אותו בעמוד הנוכחי ומוסיף אותו לרשימת ההיסטורייה.
 
 
window.location.href בתחביר הבא
 

window.location.href = 'sUrl';

 
 אותו התנהגות של navigate
 
 
window.location.assign - בתחביר הבא

window.location.assign('http://www.google.com');

אותו התנהגות של navigate
 
window.location.replace מקבל בתחביר הבא

window.location.replace('http://www.google.com');

מחליף בעמוד הנוכחי אבל לא מוסיף להיסטורייה.
 
 
window.showModalDialog פותח חלון חדש בדיאלוג כלומר עד שהחלון לא יסגר לא יוכלו לעשות כלום בחלון הפותח - מקבל בתחביר הבא
 

var vReturnValue = window.showModalDialog(sURL [, vArguments] [, sFeatures]);

הפרמטר sUrl חובה - איזה עמוד לפתוח.
 
הפרמטר vArguments אופציונלי - ארגומנטים לשליחה לעמוד שנפתח כדיאולג, ניתן לגשת לפרמטרים האלו בחלון הנפתח בעזרת window.dialogArguments
 
הפרמטר sFeatures אופציונלי - משפיע איך יראה החלון (גולד מיקום ועוד) לרשימה המלאה ניתן לעיין בלינק לעיל.
 
הפרמטר שחוזר מהפונקצייה הוא מה שיושם לתוך המאפיין returnValue בחלון שנפתח כדיאלוג
 
למשחק עם הפרמטרים השונים ליצירת חלון מודלי. אפשר ללחוץ כאן
לפיתרון בעיית ה - Post Back בחלון מודלי. אפשר לקרוא כאן
 
 
window.showModelessDialog
דומה ל - showModalDialog אבל נותן את האפשרות לחזור לפוקוס לחלונות אחרים כשהוא נשאר מעל כל החלונות.
 
 
 

הצגת הודעות למשתמש בצד הלקוח

 

כדי להציג הודעות למשתמש ב - Javascripr בדרך כלל משתמשים ב - alert ה - syntax הוא
 

alert('meesage');

נקבל כתוצאה
 
alert
 
 
אופצייה נוספת היא להשתמש ב - confirm ה - syntax הוא
 

var res = confirm('meesage ?');

if (res == true) {

}

else {

}

נקבל כתוצאה
 
confirm
 
במידה שהמשתמש ילחץ על ok המשתנה res יקבל את הערך true.
 
 
אופצייה שלישית ומעניינת היא להשתמש ב - promt.  ה - syntax הוא
 

var res = prompt('meesage', 'default result');

 
נקבל כתוצאה
 
promt
 
 
במידה והמשתמש ילחץ על ok ההשתנה res יקבל את מה שכתוב בתיבת הטקסט במידה והמשתמש ילחץ על cancel המשתנה res יהיה null

close (start) page after project load in visual studio 2008

 

ב - Visual Studio 2010 סוף סוף הוסיפו מיקרוסופט את האפשרות של Close page after project load על ה - Start Page.
 
כדי שזה יקרה גם ב - Visual Studio 2008 תוכלו להוסיף את המאקרו הבא.
 
 
תחת Tools -> Macros -> Macros IDE  או All + F11
 
נלחץ פעמיים על MyMacros (זה TreeView - רק שלא רואים את סימן הפלוס)
 
נכנס ל - EnvironmentEvents
 
ונוסיף את קטע הקוד הבא
 
 

    Private Sub SolutionEvents_Opened() Handles SolutionEvents.Opened

        If DTE.ActiveWindow.Caption = "Start Page" Then

            DTE.ActiveWindow.Close()

        End If

    End Sub

 
אחרי שתשמרו ותצאו בכל פעם שתפתחו פרוייקט במידה וה - Start Page פתוח הוא יסגר.
More Posts Next page »