Tags: , | Categories: C# Posted by talgiladi on 12/25/2007 9:44 AM | Comments (5)

ראיתי מספר פעמים ששאלו על FCKEditor בקשר להתקנה ותיפעול אז צירפתי הוראות פשוטות אני מקווה שלא תתקלו בבעיות...

קודם נלך לאתר שלהם ונוריד את הגירסה הרגילה

fckdownload

אחר כך נוריד את התוסף לדוט נט

fcknet

נפתח את קובץ הזיפ הראשון לתיקיה בשם fckeditor בתיקית ה root של האתר שלנו
לקובץ השני שהוא התוסף לדוט נט אנחנו צריכים להוסיף הפניה פשוט ולהראות לויז'ואל סטודיו את הקובץ המתאים (נמצא בתיקיית bin\Release\2.0 בזיפ השני שפתחנו)
כעת נלך לדף שבו אנו רוצים להוסיף את האדיטור, ונוסיף למעלה הפניה ל dll של האדיטור כך:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%@ Register Assembly="FredCK.FCKeditorV2" Namespace="FredCK.FCKeditorV2" TagPrefix="FCKeditorV2" %>

ונוסיף את האדיטור במקום שאנו רוצים בדף כמו כל קונטרול אחר

<FCKeditorV2:FCKeditor ID="FCKeditor1" BasePath="fckeditor\" runat="server" Height="345px"> </FCKeditorV2:FCKeditor>

הפרמטר הכי חשוב כאן זה בעצם הנתיב לספריה שלו - שזה אצלנו fckeditor ששם הוא מוצא את כל הקבצים שלו
בקוד שלנו אנו ניגשים אליו לפי ה ID כמובן וכך אפשר להכניס לו HTML מראש ולמשוך אחר כך את ה HTML שהמשתמש ערך בו
ישנה עוד נקודה אחת רק... קטנה אבל בעייתית, למרות שבגירסה האחרונה היא לא התעוררה, אז אתם יכולים להתפלל שהיא גם לא תופיע... אבל בכל מקרה טוב לדעת על הנושא.
כידוע יש את אלמנט ההתקפה שנקרא XSS ומתבצע דרך סקריפטים שנשלחים לשרת ואז מוצגים שוב למשתמשים. שרת הדוט נט, במטרה להפחית את הסבירות, זורק exception אם הוא מקבל לשרת כל מידע שמתחיל עם > ואחריו איזושהי אות ,מה שאומר שזה בעצם כל תגית ב html. כך שאם תנסו בטקסט בוקס רגיל או באיזה פרמטר בשורת הכתובת להכניס את המילה <script> תקבלו שגיאה מאוד נחמדה מהשרת:

"A potentially dengerous Request..."

קוראים לתכונה הזאת Request Validation וניתן לבטל את זה, רק שתדעו שפעם מישהו אמר:

" אתה חייב לדעת טוב מאוד מה אתה עושה כדי לבטל את ה Request Validation, ואם אתה אכן יודע טוב מאוד מה אתה עושה, אז אתה לא תבטל את ה Request Validation"
אני ביטלתי כמה פעמים :)

בכל מקרה כדי לעשות זה פשוט נוסף בשורה הראשונה של הגדרת הדף את הפרמטרים

ValidateRequest="false" EnableEventValidation="false"

להורדת פרוייקט דוגמה

 

Technorati Tags: ,

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags: | Categories: Controls Posted by talgiladi on 12/9/2007 5:04 PM | Comments (4)
Technorati Tags:

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

 wc_addControl

או שניתן ליצור פרוייקט חדש, והתוצאה שלו תהיה dll שניתן להוסיף לאתר שלנו

 wc_createProject

יש הבדלים בין השיטות. בדרך הראשונה, הקונטרול יהיה זמין רק לאתר שבו יצרתי אותו, אני לא אוכל להשתמש בו באתרים אחרים. מצד שני, כל תהליך הבניה הוא קל יותר כי לא צריך לקמפל מחדש כל פעם , הוא מתקפל אוטומטית כמו כל שאר הדפים באתר. הקונטרול בצורה הזאת יורש מהמחלקה System.Web.UI.UserControl
בשיטה השניה זה הפוך כמובן... אני יכול להוסיף הפניה ל dll שנוצר מכל פרוייקט ווב שארצה, אך מצד שני פחות נוח בתהליך הפיתוח לקמפל מחדש כל פעם את הפרוייקט. ישנם עוד הבדלים קטנים בצורת כתיבת הקוד ובקריאת לאירועים של הקונטרול . הקונטרול בצורה הזאת יורש מ WebControl

אנו נבחר בשיטה הראשונה... ניצור פרוייקט מסוג WebCustomControl .
כעת נשנה את השם של המחלקה שנוצרה באופן אוטומטי כי השם הזה הוא חלק ממה שהמשתמש יראה כשהוא ירצה לזרוק את הקונטרול על דף הווב שלו, וניבחר משהו כמו LightCaptchaValidator
קיבלנו מחלקה שנראית כך:

[ToolboxData("<{0}:LightCaptchaControl runat=server></{0}:LightCaptchaControl>")]

    public class LightCaptchaControl : WebControl

רק לפני שנמשיך צריכים לעשות איזו שינוי קטן, תוסיפו עוד Interface כך שהגדרת המחלקה תיראה כך:

public class LightCaptchaControl : WebControl, INamingContainer

שאינה רלוונטית לקונטרול שלנו. כפי שניתן לנחש, התגית ToolboxData אומרת כיצד יראה הקוד בדף ה aspx לאחר שנזרוק את הקונטרול על הדף, כש {0} זה הערך שניתן בדף ל TagPrefix

עוד יש לנו במחלקה דוגמה לפרופרטי שניתן לערוך ב Form Designer. ה Form Designer בעצם מציג את כל הפרופרטיס שיש לנו במחלקה ולכן אם אנו רוצים "להעלים" מהמשתמש משהו, יש להוסיף תגית

[Browsable(false)]

מעל פרופרטי שאמור להיות מוחבא. התגית:

[Category("Appearance")]

אומרת פשוט באיזה קטגוריה יוצג הפרופרטי הזה ו DefaultValue הוא כמובן ערך ברירת המחדל... שימו לב שבפרופרטיס של ווב קונטרול, שלא כמו בפרופרטיס של מחלקה רגילה, אנו שומרים ומושכים את המידע מה ViewState, ולא ממשתנה מחלקה, כי הרי הקונטרול הזה נוצר מחדש בכל פעם שהמשתמש מבקש את הדף או עושה פוסטבאק לשרת, והדרך היחידה לשמור על ערך המשתנים הוא ב ViewState.
המתודה שיש לנו במחלקה:

protected override void RenderContents(HtmlTextWriter output)

        {

            output.Write(Text);

        }

המתודה הזאת נקראת על ידי הדף כשהוא מוכן לשלב את פלט ה HTML של הקונטרול שלנו בתוכו. היא המתודה שבה אנו כותבים את הפלט הסופי של הקונטרול שלנו וזהו בעצם ה HTML שיוצג על הדף. כפי שניתן לראות המחלקה מקבלת פרמטר מסוג HtmlTextWriter(כתבתי עליו כמה מילים במקום אחר).
אם נשים את הקונטרול עכשיו על דף ונריץ, נקבל בעצם טקסט ריק, כי זה מה שהמתודה הזאת מדפיסה לדף
טוב, נמשיך. מה יעשה הקונטרול שלנו? הוא יהיה כמו captcha זולה... אנו נציג טקסט בוקס, עם שאלה במתמטיקה לידו, והגולש אמור להכניס את התשובה. כשעושים פוסטבאק לשרת הקונטרול שלנו בודק את התשובה ויכול להודיע לדף שאכן היא נכונה ורוב הסיכויים שהגולש איננו סקריפט אוטומטי. כמובן שאי אפשר להציג את השאלה בצורת טקסט פשוט כי אז הסקריפט פשוט ימצא את הפיתרון, אבל זו כבר בעיה אחרת שאולי יהיה לנו זמן גם לפתור...
אז אנחנו צריכים לייבל, שיודיע לגולש שהוא אמור לענות על השאלה שלנו, טקסט בוקס שאליו יכניסו את התשובה, ועוד לייבל שיציג את התרגיל במתמטיקה. כמובן שאפשר להוסיף ולידטור, ואפשר אפילו להוסיף לינק כדי שאפשר יהיה לבחור תרגיל אחר אבל זה לא עכשיו...
כדי להוסיף קונטרולים אחרים לקונטרול שלי , אני צריך להוסיף מתודה אחרת שנקראת על ידי הדף והיא:

protected override void CreateChildControls()

        {

        }

שימו לב שכאן אנו רק מוסיפים את הקונטרולים, אבל במתודה RenderContents אנו גם נבקש מכל אחד מהם לרנדר את עצמו לתוך ה HTML של כל הקונטרול שלנו...

protected override void CreateChildControls()

        {

            ////the label with the text asking

            ///the user to answer the question

            Label lblText = new Label();

            lblText.Text = this.Text;

            lblText.ID = "lblText";

            this.Controls.Add(lblText);

            ////the text box with the answer

            TextBox txtAnswer = new TextBox();

            txtAnswer.ID = "txtAnswer";

            this.Controls.Add(txtAnswer);

            ////The label with the methematics question

            Label lblQuestion = new Label();

            lblQuestion.ID = "lblQuestion";

            this.Controls.Add(lblQuestion);

        }

ללייבל lblQuestion עדיין לא שמתי ערך טקסט כי עדיין לא חשבנו איך ניצור את התרגיל המתמטי, אבל נחזור לזה אחר כך. lblText קיבלה את ערך הטקסט של הפרופרטי Text מהקונטרול שלנו, כך שכשהמשתמש יעצב את הקונטורל וישנה לו את ערך הטקסט, זה מה שיוצג לגולש.

בואו נוסיף אתר לפרוייקט שלנו, כדי שנוכל לראות את הקונטרול שלנו בפעולה(או שאפשר להוסיף הפניה ל dll מאתר קיים כמובן)addWebSite

נלך לעיצוב הדף, ארגז כלים, לחצן ימני - choose items כדי להוסיף את הקונטרול שלנו לארגז הכלים

ChooseItems

בחלון שנפתח נלחץ על Browse ונחפש את תיקיית הפרוייקט שלנו, שם בתוך תיקיית bin\debug נמצא את ה dll שלנו. אם הוא לא שם אז לא עשיתם build לפרוייקט או שתחפשו בספריית release. לחיצה על OK והקונטרול מופיע בארגז הכלים. תמשכו אותו לדף. אם יש איזו בעיה אז אתם תראו, אם לא, אז אנו רואים דף חלק... ואיפה הקונטרולים שלנו? זה שהוספנו אותם זה לא מספיק עדיין, אנו צריכים לרנדר אותם...
אז בחזרה לקונטרול שלנו, כבר יש שם פונקציה מתאימה:

 protected override void RenderContents(HtmlTextWriter output)

אפשר לרנדר בריצה בלולאה:

for (int i = 0; i < this.Controls.Count; i++)

            {

                this.Controls[i].RenderControl(output);

            }

אבל אני מעדיף למצוא כל אחד מהקונטרולים ולרנדר אותו:

 Label lbl = (Label)this.FindControl("lblText");

            lbl.RenderControl(output);

כך תעברו על כל הקונטרולים שלנו. בצורה הזאת נוכל לשנות מאפיינים בהמשך...
עכשיו אם נחזור לטופס שלנו אנו אמורים לראות טקסט בוקס (את הלייבלים לא נראה כי לא נתנו להם ערך טקסט) אם אתם לא רואים תעתיקו מחדש את ה dll של הקונטרול לתיקית bin של הפרוייקט(
תנו ערך למאפיין טקסט על הטופס שלכם

setTextValue

רפרש קטן על הדף )לחצן ימני( ואתם אמורים גם לראות את הטקסט ליד הטקסט בוקס. זה יהיה גם רעיון טוב לתת ערך ברירת מחדל למאפיין הזה, אז בחזרה לקונטרול, תלכו למאפיין Text, יש שם תגית בשם DefaultValue, תנו לה איזה ערך שתרצו, וגם ב Get של המאפיין תחזירו את אותו טקסט במקרה והוא ריק:

[Bindable(true)]

        [Category("Appearance")]

        [DefaultValue("Please enter the answer")]

        [Localizable(true)]      

        public string Text

        {

            get

            {

                String s = (String)ViewState["Text"];

                return ((s == null) ? "Please enter the answer" : s);

            }

            set

            {

                ViewState["Text"] = value;

            }

        }

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

והמחלקה שלנו:

public class Question:ICloneable

    {

        private double _answer;

        public double Answer

        {

            get { return _answer; }

            set { _answer = value; }

        }

        private List<string> _items;

        public List<string> Items

        {

            get {

                if (_items == null)

                {

                    _items = new List<string>();

                }

                return _items; }

            set { _items = value; }

        }

        #region ICloneable Members

        public object Clone()

        {

            Question q = new Question();

            q.Answer = this.Answer;

            q.Items = new List<string>();

            q.Items.AddRange(this.Items);

            return q;

        }

        #endregion

    }

המחלקה מכילה בעצם מערך עם הנתונים שצריך להציג לגולש (מספרים וסימני חשבון) ואת התוצאה הסופית של התרגיל.
עכשיו ניצור לנו מחלקה שתייצר את התרגיל ותמלא אותו בנתונים:

    public class QuestionsGenerator

    {

        private Question _question;

        private Question Question

        {

            get

            {

                if (_question == null)

                {

                    Generate();

                }

                return _question;

            }

        }

        private int _itemsCount;

        public int ItemsCount

        {

            get

            {

                return (int)Math.Max(_itemsCount, 2);

            }

            set { _itemsCount = value; }

        }

        private int _maxNumber;

        public int MaxNumber

        {

            get

            {

                return (int)Math.Max(10, _maxNumber);

            }

            set { _maxNumber = value; }

        }

        public QuestionsGenerator()

        {

            this.MaxNumber = 10;

            this.ItemsCount = 4;

        }

        public double Result

        {

            get

            {               

                return Question.Answer;

            }

        }

        public Question Source

        {

            get

            {

                return (Question)Question.Clone();

            }

        }

        public override string ToString()

        {           

            StringBuilder sb = new StringBuilder();

            for (int i = 0; i < this.Question.Items.Count; i++)

            {

                sb.Append(Question.Items[i]);

                sb.Append(" ");

            }

            return sb.ToString();

        }

        private void Generate()

        {

            this._question = new Question();

            Question.Answer = new Random().Next(0, MaxNumber);

            Question.Items.Add(Question.Answer.ToString());

            for (int i = 0; i < ItemsCount-1; i++)

            {

                AddPair();

            }      

        }

        private enum Sign

        {

            Plus,

            Minus,

            Multiply,

            Divide

        }

        private void AddPair()

        {

            System.Security.Cryptography.RandomNumberGenerator rng = System.Security.Cryptography.RandomNumberGenerator.Create();

            byte[] b=new byte[1];

            rng.GetBytes(b);

            int next = (int)b[0] % MaxNumber;

            Sign s = (Sign)Enum.Parse(typeof(Sign), ((int)b[0]%4).ToString());

            switch (s)

            {

                case Sign.Plus:

                    Question.Answer = Question.Answer + next;

                    Question.Items.Add("+");

                    break;

                case Sign.Minus:

                    Question.Answer = Question.Answer - next;

                    Question.Items.Add("-");

                    break;

                case Sign.Multiply:

                    Question.Answer = Question.Answer * next;

                    Question.Items.Add("*");

                    break;

                case Sign.Divide:

                    bool found = false;

                    for (int i = 0; i < 5; i++)

                    {

                        if (Question.Answer % next != 0)

                        {

                            next++;

                        }

                        else

                        {

                            found = true;

                            break;

                        }

                    }

                    if (!found)

                    {

                        next = 1;//dont' get complicated now...

                    }

                    Question.Answer = (int)(Question.Answer / next);

                    Question.Items.Add("/");

                    break;

            }

            Question.Items.Add(next.ToString());

        }

    }

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

lbl = (Label)this.FindControl("lblQuestion");

            QuestionsGenerator qg = new QuestionsGenerator();

            lbl.Text = qg.ToString();

            lbl.RenderControl(output);

mathquestion

נמשיך... אנו צריכים לשמור את התוצאה של התרגיל ב Session של הגולש כדי שנידע אם הוא ענה נכון, אז נוסיף עוד שורה קטנה:

lbl = (Label)this.FindControl("lblQuestion");

            QuestionsGenerator qg = new QuestionsGenerator();

            HttpContext.Current.Session.Add("LightCaptchaControl_answer", qg.Result);

            lbl.Text = qg.ToString();

            lbl.RenderControl(output);

עכשיו נוסיף פרופרטי שיאפשר לדף שבתוכו הקונטרול לבדוק אם התוצאה אכן תקינה

[Browsable(false)]

        public bool IsValid

        {

            get

            {

                double result;

                if (double.TryParse(((TextBox)this.FindControl("txtAnswer")).Text, out result))

                {

                    if (HttpContext.Current.Session["LightCaptchaControl_answer"] != null)

                    {

                        return result == (double)HttpContext.Current.Session["LightCaptchaControl_answer"];

                    }

                }

                return false;

            }

        }

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

 protected void btnSubmit_Click(object sender, EventArgs e)

    {

        bool valid = this.LightCaptchaControl1.IsValid;

    }

נראה לי שעדיף לנו גם ליצור פונקציה שתערבל קצת את התצוגה של התרגיל, כי הרי מי שבונה סקריפט אוטומטי למילוי טפסים יצטרך בסך הכל להשקיע עוד 5 דקות כדי לקרוא את התרגיל שלנו ולהכניס את התשובה הנכונה, אז הוספתי פונקציה פשוטה, אבל שתדרוש קצת יותר מאמץ מבונה הסקריפטים, אתם יכולים לסבך אותה עוד לפי אותו עיקרון: 

 public string ToRandomHtml()

        {           

            char[] chars="abcdefghijklmnopqrstuvwxyz1234567890".ToCharArray();

            StringBuilder sb = new StringBuilder();

            for (int i = 0; i < this.Question.Items.Count; i++)

            {

                System.Security.Cryptography.RandomNumberGenerator rng = System.Security.Cryptography.RandomNumberGenerator.Create();

                byte[] b = new byte[1];

                rng.GetBytes(b);

                int ran = (int)b[0] % 5;

                switch (ran)

                {

                    case 0:

                        sb.Append(Question.Items[i]);

                        sb.Append(new String(' ',new Random().Next(4)));

                        break;

                    case 1:

                        sb.Append(Question.Items[i]);

                        sb.Append("<span style=\"display:none\">");

                        sb.Append(Question.Items[i]);

                        sb.Append("</span>");

                        break;

                    case 2:

                        sb.Append("<span style=\"display:none\">");

                        sb.Append(Question.Items[i]);

                        sb.Append("</span>");

                        sb.Append(Question.Items[i]);

                        break;

                    case 3:

                        sb.Append("<b>");

                        sb.Append(Question.Items[i]);

                        sb.Append("</b>");

                        break;

                    case 4:

                        sb.Append("<u>");

                        sb.Append(Question.Items[i]);

                        sb.Append("</u>");

                        break;

                }

            }

            return sb.ToString();

        }

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

להורדת הפרוייקט ודוגמה

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags: , , | Categories: JavaScript Posted by talgiladi on 12/4/2007 3:40 PM | Comments (4)
Technorati Tags: ,,

.התחלנו כבר לדבר על דיפדוף יעיל בדטה בייס בעבר, עכשיו נמשיך את זה לצד הלקוח
נשתמש באג'קס ליישום הדיפדוף (אני משתמש ב framework לנוחות, אבל כל אג'קס יעשה את העבודה)
נתחיל בבניית הטבלה בדף, אנחנו כבר יודעים איך למשוך את הנתונים כך שנקבל רק את השורות המתאימות לדף שלנו, אז פשוט נזרוק את כל הנתונים לדף בצורת טבלה. את הטבלה נשים בתוך div עם id

נבנה בדף פונקציה שתמשוך לנו את הנתונים מה ADP

private string GetTable()
{
    int pagenum;
    if (!int.TryParse(Request.Params["pagenum"], out pagenum))
    {
        pagenum = 1;
    }
    int rowsPerPage = 10;
    string sortByColumn = Request.Params["sortName"];
    if (string.IsNullOrEmpty(sortByColumn)) sortByColumn = "id";
    string sortOrder = Request.Params["sortOrder"];
    if (string.IsNullOrEmpty(sortOrder)) sortOrder = "asc";
    DataTable table = ADP.GetUsers(pagenum, rowsPerPage, sortByColumn, sortOrder);
    StringBuilder sb = new StringBuilder();
    sb.Append("<table><tr><td>id</td><td>name</td></tr>");
    foreach (DataRow dr in table.Rows)
    {
        sb.Append("<tr>");
        sb.Append("<td>");
        sb.Append(dr["id"]);
        sb.Append("</td>");
        sb.Append("<td>");
        sb.Append(dr["name"]);
        sb.Append("</td>");
        sb.Append("</tr>");
    }
    sb.Append("</table>");
    return sb.ToString();
}

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

<div id="div_data"><%=myTable%>
</div>

כעת נבנה את שורת הדפדוף, אני אשתמש בפשוטה ביותר כרגע. קודם צריכים לדעת כמה נתונים יש בדטה בייס, נמשוך את מספר השורות ונחלק במספר השורות שאנו מציגים בדף כדי לדעת את מספר הדפים

int rowsCount =ADP.GetUsersCount();
int rowsPerPage = 10;
int totalPages=(int)Math.Ceiling((double)rowsCount / rowsPerPage);

הפייג'ר עצמו בדף html:

<%for (int i=0;i<totalPages;i++)
{ %>
<a href="javascript:doPaging(<%=(i+1)%>)"><%=(i+1)%></a>
%<}%>

ופונקציית ג'אווה קטנה

<script type="text/javascript">
    var curpage=1;
    var sortName='id';
    var sortDirection='asc';
  
    function doPaging(pagenum){
        curpage=pagenum;
            var url='mypage.aspx?action=paging&pagenum='+curpage+'&sortName='+ sortName+'&sortOrder'+sortDirection;
        new Ajax.Request(url,{onSuccess:function(t){
            if (t.responseText=='error'){
                alert('error!');
            }else{
               
                document.getElementById('div_data').innerHTML=t.responseText;
            }
        }});
}
</script>

זהו, בשביל הדפדוף זה מספיק... רק בשביל המיון צריך עוד 2 דברים קטנים לעשות. קודם כל כשאנו בונים את הטבלה, אז בכותרות להוסיף הפניה לפונקציה של ג'אווה סקריפט כדי שכשמקליקים על הכותרת יתבצע מיון
נשנה מעט את איך שבנינו את הטבלה מקודם במקום לכתוב id בכותרת נכתוב <a href=\"javascript:doSort('id');\">id</a>  ,וכך לגבי שאר הכותרות, ונבנה את הפונקציה המתאימה בג'אווה סקריפט

function doSort(columnName){
        if (sortName==columnName){
            if (sortDirection=='asc'){
                sortDirection='desc';
            }else{
                sortDirection='asc';
            }
        }else{
            sortName=columnName;
        sortDirection='asc';
    }
            var url='mypage.aspx?action=paging&pagenum='+curpage+'&sortName='+ sortName+'&sortOrder'+sortDirection;
        new Ajax.Request(url,{onSuccess:function(t){
            if (t.responseText=='error'){
                alert('error!');
            }else{
                document.getElementById('div_data').innerHTML=t.responseText;
            }
        }});
}
</script>

הפונקציה הזאת רק מסדרת את הפרמטר של שם העמודה למיון והסדר (עולה יורד) וממשיכה כרגיל כמו הפונקציה הקודמת. זהו בעיקרון, ניתן להוסיף גם חיפוש באותה שיטה  למי שרוצה...

להורדת דוגמה (ללא דטה בייס כמובן)

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags: , | Categories: C# Posted by talgiladi on 12/2/2007 10:02 AM | Comments (4)

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

  • לנקודה חשובה, התוכנה לא מתריעה על שגיאות שהיו! אתם צריכים לשים שגודל הקובץ הסופי אכן השתנה ושהוא לא 0...

  • לעשות גיבוי לספריה של הקבצים כי אם כן היו שגיאות הלך לכם הקובץ (אבל ברור שהיא לא נוגעת בקבצי המקור)

  • כמו כן התוכנה קצת מתעצבנת אם יש באותה תיקיה קבצי pdb שנשארו מהפיתוח, אז תמחקו אותם קודם

  • התוכנה מקבלת רשימת קבצים לאיחוד, הקובץ הראשון הוא הקובץ העיקרי - זה שמשתמש באחרים

לאחר ההתקנה השימוש פשוט מאוד , פשוט תריצו אותה עם רשימת הקבצים לאיחוד ואת השם שאתם רוצים שיינתן לקובץ הסופי:

Ilmerge MyApplication.exe ThirdPartyApplication.dll /out:MyApplication.exe

ניתן להוריד את התוכנה מאתר מיקרוסופט , וראיתי שכבר כתבו כלים גרפיים להריץ אותה, כשהראשון נכתב על ידי ישראלים :)

Technorati Tags: ,

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5