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

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

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

January 2010 - Posts

ביעבוע של אירועי המקלדת לטופס (WinForm - KeyPreview)

 

נניח שאתם כותבים אפליקצייה WinForm ונרשמים לאירוע של KeyDown ואתם עושים משהו כזה
 

private void Form1_KeyDown(object sender, KeyEventArgs e)

{

    Text = e.KeyCode.ToString();

}

 
זה יעבוד נהדר - עד שיהיה לכם פקדים על הדף - ברגע שזה יקרה (כלומר יהיו לכם פקדים על הטופס) הם בולעים את האירועים של המקלדת ולכן הקוד שלכם לא יקרה.
 
כדי לפתור את זה, צריך להגדיר את המאפיין KeyPreview ל - true.
 
כשתעשו את זה יגרום לאירועים להגיע קודם לטופס.
 
מתוך הדוקומנטצייה:
 
Gets or sets a value indicating whether the form will receive key events before the event is passed to the control that has focus.
Posted: Jan 30 2010, 08:45 PM by Shlomo | with no comments
תגים:, , ,

איך לקבל ערכים מ - Query String ב JavaScript - גרסה שנייה Version 2 for FindByName

 

כתבתי בעבר איך אפשר לקבל ערכים מ - QueryString ב - JavaScript.
 
ראיתי גרסה יעילה יותר ל - FindByName
 
 

function FindByName(key, search) {

    return gup(key, search);

}

 

function gup(name, where) {

    if (!where)

        where = window.location.href;

    name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");

    var regexS = "[\\?&]" + name + "=([^&#]*)";

    var regex = new RegExp(regexS);

    var results = regex.exec(where);

    if (results == null)

        return "";

    else

        return unescape(results[1]);

}

Posted: Jan 24 2010, 06:32 PM by Shlomo | with no comments
תגים:, ,

string.ToLower ToTitleCase

 

חבר לעבודה (רון כהן) שאל אותי איך אפשר לקבל את הפונקציונליות של ToLower עבור האות הראשונה של כל מילה, לדוגמא shlomo goldberg יהפוך ל - Shlomo Goldberg.
 
זה הקוד שנתתי לו
 

string str = "shlomo goldberg";

 

CultureInfo c = new CultureInfo("en-US");

str = c.TextInfo.ToTitleCase(str);

 
הוא כמובן הפך את זה ל - extension methods
 
 

namespace System

{

    public static class StringExtension

    {

        public static string ToTitleCase(this string str)

        {

            CultureInfo c = new CultureInfo("en-US");

            return c.TextInfo.ToTitleCase(str);

        }

    }

}

 

static void Main(string[] args)

{

    string str = "shlomo goldberg";

    str = str.ToTitleCase();

}

עבודה עם Services ו - Console Application

 

הרבה פעמים כשאנחנו עובדים עם Services ה - host שלהם הוא Windows Service, מה שמתסכל לעבוד בצורה הזאת זה שבזמן פיתוח כדי לדבג צריך כל פעם לעשות Attach to process ובכל קומפילציה צריך לעצור את ה - Serivce ולהפעיל אותו מחדש אחרי הקופמילציה (מה שלוקח קצת זמן).
 
אני משתמש ברעיון מעניין (נדמה לי שזה שייך לאלכס מחברת QualiSystems)
 
נוסיף למחלקה שיורשת מ - ServiceBase את המתודת הבאות
 

public void Open()

{

    OnStart(null);

}

 

public void Close()

{

    OnStop();

}

 
 
כעת ב - Main נכתוב את הקוד הבא
 

bool console = args.Length > 0 && args[0] == "console";

 

var service = new MyService();

 

if (!console)

{

    ServiceBase[] ServicesToRun;

    ServicesToRun = new ServiceBase[]

    {

        service

    };

 

    ServiceBase.Run(ServicesToRun);

}

else

{

 

    service.Open();

    Console.WriteLine("Service is running...");

    Console.ReadKey();

    service.Close();

    Console.WriteLine("ervice is stoped");

}

 
 
מה שנשאר זה ב - Command Line Arguments במאפיינים של הפרוייקט בטאב Debug לכתוב console.
 
וכעת אפשר פשוט להריץ כמה פרוייקטים במקביל בזמן פיתוח ולעבוד בצורה פשוטה.

Filtering with ComboBox (DropDownList) in telerik grid (RadGrid)

 

לא מזמן קנינו את החבילה של Telerik ל - Web, אני חושב שזה בחירה נבונה לעבוד עם הפקדים שלהם.
 
בכל מקרה רציתי להדגים כאן, איך ניתן לייצר גריד שיש לו את האפשרות לפלטר בעזרת ComboBox שנותן לבחור מתוך הערכים.
 
Grid with combo filter
 
 
לגריד של telerik יש מנגנון פילטרניג מובנה - אבל אין את האפשרות ל - Combo.
כדי שיהיה לנו Combo צריך לעשות את הדבר הבא.
 
כתבתי מחלקה כללית שתשמש אותי בכל הפרוייקטים שאני עובד עם Telerik.
 
אנחנו צריכים לרשת מהמחלקה GridTemplateColumn ולדרוס את המתודות הבאות
 

SetupFilterControls

SetCurrentFilterValueToControl

GetCurrentFilterValueFromControl

SupportsFiltering

ConvertValueIfEmpty

 
והנה המימוש

public class DDLFilterColumn : GridTemplateColumn

{

 
המתודה הראשונה

protected override void SetupFilterControls(TableCell cell)

{

    RadComboBox rcBox = InitProperties();

    cell.Controls.Add(rcBox);

 

    if (!DesignMode)

    {

        FireFillingItems(this, new DDLFilterItemsEventArgs(rcBox));

    }

}

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

private RadComboBox InitProperties()

{

    RadComboBox rcBox = new RadComboBox();

    rcBox.ID = ("DropDownList1" + this.UniqueName);

    rcBox.SelectedIndexChanged += rcBox_SelectedIndexChanged;

    rcBox.Width = this.FilterControlWidth;

    rcBox.AutoPostBack = true;

    rcBox.DataTextField = this.DataField;

    rcBox.DataValueField = this.DataField;

 

    return rcBox;

}

 
מייצר את ה - Combo ונרשם לאירוע של SelectedIndexChanged שבו אנחנו נספר לגריד שאנחנו רוצים לפלטר
 

void rcBox_SelectedIndexChanged(object sender, RadComboBoxSelectedIndexChangedEventArgs e)

{

    GridFilteringItem filteringItem = (GridFilteringItem)(((RadComboBox)sender).Parent.Parent);

    filteringItem.FireCommandEvent("Filter", new Pair());

}

 
נחזור למתודה הראשונה, ראינו את הקוד הבא
 

if (!DesignMode)

{

    FireFillingItems(this, new DDLFilterItemsEventArgs(rcBox));

}

 
כדי שהמחלקה תהיה כללית - כתבתי את הקוד הבא (מחוץ למחלקה של DDLFilterColumn)
 

public delegate void DDLFilterItemsEventHandler(object sender, DDLFilterItemsEventArgs args);

 

public class DDLFilterItemsEventArgs : EventArgs

{

    public RadComboBox ComboBox { get; private set; }

 

    public DDLFilterItemsEventArgs(RadComboBox comboBox)

    {

        ComboBox = comboBox;

    }

}

 
ובמחלקה שלנו הוספתי אירוע מהסוג של ה - delegate
 

 

public event DDLFilterItemsEventHandler FillingItems;

 

protected virtual void FireFillingItems(object sender, DDLFilterItemsEventArgs args)

{

    if (FillingItems != null)

    {

        FillingItems(sender, args);

    }

}

 
במידה ונרשמו לאירוע (מה - aspx) האירוע יופעל מיד אחרי יצירת ה - Combo.
 
 
נעבור למתודות הבאות.
עד עכשיו ראינו את המתודה שיוצרת את ה - Combo, כמו שכתבתי אנחנו גם צריכים להגדיר איך מוצאים את הערך עבור ה - Filter ואיך מכניסים פנימה
 

protected override void SetCurrentFilterValueToControl(TableCell cell)

{

    if (this.CurrentFilterValue != string.Empty)

    {

        var rcmi = ((RadComboBox)cell.Controls[0]).Items.FindItemByText(this.CurrentFilterValue);

        if (rcmi != null)

        {

            rcmi.Selected = true;

        }

    }

}

 

 

protected override string GetCurrentFilterValueFromControl(TableCell cell)

{

    string currentValue = ((RadComboBox)cell.Controls[0]).SelectedItem.Text;

 

    CurrentFilterFunction = (currentValue != string.Empty) ?

                        GridKnownFunction.EqualTo :

                        GridKnownFunction.NoFilter;

 

    return currentValue;

}

 
 
כמובן שצריך להוסיף את הקוד הבא:
 

public override bool SupportsFiltering()

{

    return true;

}

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

protected override object ConvertValueIfEmpty(string value)

{

    if (value == null || value.ToString() == string.Empty)

    {

        return " ";

    }

    return value.ToString();

}

 
 
 
 
 
כעת נראה את הדף
 

<telerik:RadGrid ID="RadGrid1" runat="server" OnNeedDataSource="RadGrid1_NeedDataSource"

    AllowFilteringByColumn="true" AutoGenerateColumns="false">

    <MasterTableView>

        <Columns>

            <telerik:DDLFilterColumn DataField="a" HeaderText="a" UniqueName="a"

                OnFillingItems="a_DDLFiltering">

                <ItemTemplate>

                    <asp:Label ID="lbl1" runat="server" Text='<%# Eval("a") %>'></asp:Label>

                </ItemTemplate>

            </telerik:DDLFilterColumn>

            <telerik:DDLFilterColumn DataField="b" HeaderText="b" UniqueName="b"

                OnFillingItems="a_DDLFiltering">

                <ItemTemplate>

                    <asp:Label ID="lbl2" runat="server" Text='<%# Eval("b") %>'></asp:Label>

                </ItemTemplate>

            </telerik:DDLFilterColumn>

            <telerik:DDLFilterColumn DataField="c" HeaderText="c" UniqueName="c"

                 OnFillingItems="a_DDLFiltering">

                <ItemTemplate>

                    <asp:Label ID="lbl3" runat="server" Text='<%# Eval("c") %>'></asp:Label>

                </ItemTemplate>

            </telerik:DDLFilterColumn>

        </Columns>

    </MasterTableView>

</telerik:RadGrid>

 

מה שחשוב זה להגדיר את ה - DataField ואת ה - UniqeName כמו כן הגדרתי את המתודה למילוי ה - Combo (במקרה הזה מדובר באותה מתודה לכל ה - Combos)
צריך כמובן לזכור להוסיף את השורה הבאה
 

<%@ Register Assembly="WebApplication1" Namespace="Custom" TagPrefix="telerik" %>

 
קוד צד שרת:
 
 
המתודה שמביאה נתונים לגריד
 

protected void RadGrid1_NeedDataSource(object source, Telerik.Web.UI.GridNeedDataSourceEventArgs e)

{

    DataTable table = (DataTable)Session["table"];

    if (table == null)

    {

        table = CreateTable();

        Session["table"] = table;

    }

 

    RadGrid1.DataSource = table;

}

 

private static DataTable CreateTable()

{

    DataTable table = new DataTable();

    table.Columns.Add("a");

    table.Columns.Add("b");

    table.Columns.Add("c");

 

    table.Rows.Add("Day", "Private", "a");

    table.Rows.Add("Day", "Private", "b");

    table.Rows.Add("Day", "Public", "c");

    table.Rows.Add("Day", "Public", "d");

    table.Rows.Add("Evening", "Certificate", "e");

    table.Rows.Add("Evening", "Certificate", "f");

    table.Rows.Add("Evening", "Certificate", "g");

 

    return table;

}

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

protected void a_DDLFiltering(object sender, DDLFilterItemsEventArgs args)

{

    args.ComboBox.Items.Clear();

 

    List<string> list = new List<string>();

 

    DataTable table = (DataTable)Session["table"];

    for (int i = 0; i < table.Rows.Count; i++)

    {

        string text = table.Rows[i][args.ComboBox.DataValueField].ToString();

        if (!list.Contains(text))

        {

            list.Add(text);

        }

    }

 

    list.Sort();

    args.ComboBox.Items.AddRange(list.ConvertAll<RadComboBoxItem>(x => new RadComboBoxItem(x)));

 

    args.ComboBox.Items.Insert(0, new RadComboBoxItem(""));

}

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

פילטור ב - RadGrid בעזרת CmoboBox

 

לא מזמן קנינו את החבילה של Telerik ל - Web, אני חושב שזה בחירה נבונה לעבוד עם הפקדים שלהם.
 
בכל מקרה רציתי להדגים כאן, איך ניתן לייצר גריד שיש לו את האפשרות לפלטר בעזרת ComboBox שנותן לבחור מתוך הערכים.
 
Grid with combo filter
 
 
לגריד של telerik יש מנגנון פילטרניג מובנה - אבל אין את האפשרות ל - Combo.
כדי שיהיה לנו Combo צריך לעשות את הדבר הבא.
 
כתבתי מחלקה כללית שתשמש אותי בכל הפרוייקטים שאני עובד עם Telerik.
 
אנחנו צריכים לרשת מהמחלקה GridTemplateColumn ולדרוס את המתודות הבאות
 

SetupFilterControls

SetCurrentFilterValueToControl

GetCurrentFilterValueFromControl

SupportsFiltering

ConvertValueIfEmpty

 
והנה המימוש

public class DDLFilterColumn : GridTemplateColumn

{

 
המתודה הראשונה

protected override void SetupFilterControls(TableCell cell)

{

    RadComboBox rcBox = InitProperties();

    cell.Controls.Add(rcBox);

 

    if (!DesignMode)

    {

        FireFillingItems(this, new DDLFilterItemsEventArgs(rcBox));

    }

}

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

private RadComboBox InitProperties()

{

    RadComboBox rcBox = new RadComboBox();

    rcBox.ID = ("DropDownList1" + this.UniqueName);

    rcBox.SelectedIndexChanged += rcBox_SelectedIndexChanged;

    rcBox.Width = this.FilterControlWidth;

    rcBox.AutoPostBack = true;

    rcBox.DataTextField = this.DataField;

    rcBox.DataValueField = this.DataField;

 

    return rcBox;

}

 
מייצר את ה - Combo ונרשם לאירוע של SelectedIndexChanged שבו אנחנו נספר לגריד שאנחנו רוצים לפלטר
 

void rcBox_SelectedIndexChanged(object sender, RadComboBoxSelectedIndexChangedEventArgs e)

{

    GridFilteringItem filteringItem = (GridFilteringItem)(((RadComboBox)sender).Parent.Parent);

    filteringItem.FireCommandEvent("Filter", new Pair());

}

 
נחזור למתודה הראשונה, ראינו את הקוד הבא
 

if (!DesignMode)

{

    FireFillingItems(this, new DDLFilterItemsEventArgs(rcBox));

}

 
כדי שהמחלקה תהיה כללית - כתבתי את הקוד הבא (מחוץ למחלקה של DDLFilterColumn)
 

public delegate void DDLFilterItemsEventHandler(object sender, DDLFilterItemsEventArgs args);

 

public class DDLFilterItemsEventArgs : EventArgs

{

    public RadComboBox ComboBox { get; private set; }

 

    public DDLFilterItemsEventArgs(RadComboBox comboBox)

    {

        ComboBox = comboBox;

    }

}

 
ובמחלקה שלנו הוספתי אירוע מהסוג של ה - delegate
 

 

public event DDLFilterItemsEventHandler FillingItems;

 

protected virtual void FireFillingItems(object sender, DDLFilterItemsEventArgs args)

{

    if (FillingItems != null)

    {

        FillingItems(sender, args);

    }

}

 
במידה ונרשמו לאירוע (מה - aspx) האירוע יופעל מיד אחרי יצירת ה - Combo.
 
 
נעבור למתודות הבאות.
עד עכשיו ראינו את המתודה שיוצרת את ה - Combo, כמו שכתבתי אנחנו גם צריכים להגדיר איך מוצאים את הערך עבור ה - Filter ואיך מכניסים פנימה
 

protected override void SetCurrentFilterValueToControl(TableCell cell)

{

    if (this.CurrentFilterValue != string.Empty)

    {

        var rcmi = ((RadComboBox)cell.Controls[0]).Items.FindItemByText(this.CurrentFilterValue);

        if (rcmi != null)

        {

            rcmi.Selected = true;

        }

    }

}

 

 

protected override string GetCurrentFilterValueFromControl(TableCell cell)

{

    string currentValue = ((RadComboBox)cell.Controls[0]).SelectedItem.Text;

 

    CurrentFilterFunction = (currentValue != string.Empty) ?

                        GridKnownFunction.EqualTo :

                        GridKnownFunction.NoFilter;

 

    return currentValue;

}

 
 
כמובן שצריך להוסיף את הקוד הבא:
 

public override bool SupportsFiltering()

{

    return true;

}

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

protected override object ConvertValueIfEmpty(string value)

{

    if (value == null || value.ToString() == string.Empty)

    {

        return "&nbsp;";

    }

    return value.ToString();

}

 
 
 
 
 
כעת נראה את הדף
 

<telerik:RadGrid ID="RadGrid1" runat="server" OnNeedDataSource="RadGrid1_NeedDataSource"

    AllowFilteringByColumn="true" AutoGenerateColumns="false">

    <MasterTableView>

        <Columns>

            <telerik:DDLFilterColumn DataField="a" HeaderText="a" UniqueName="a"

                OnFillingItems="a_DDLFiltering">

                <ItemTemplate>

                    <asp:Label ID="lbl1" runat="server" Text='<%# Eval("a") %>'></asp:Label>

                </ItemTemplate>

            </telerik:DDLFilterColumn>

            <telerik:DDLFilterColumn DataField="b" HeaderText="b" UniqueName="b"

                OnFillingItems="a_DDLFiltering">

                <ItemTemplate>

                    <asp:Label ID="lbl2" runat="server" Text='<%# Eval("b") %>'></asp:Label>

                </ItemTemplate>

            </telerik:DDLFilterColumn>

            <telerik:DDLFilterColumn DataField="c" HeaderText="c" UniqueName="c"

                 OnFillingItems="a_DDLFiltering">

                <ItemTemplate>

                    <asp:Label ID="lbl3" runat="server" Text='<%# Eval("c") %>'></asp:Label>

                </ItemTemplate>

            </telerik:DDLFilterColumn>

        </Columns>

    </MasterTableView>

</telerik:RadGrid>

 

מה שחשוב זה להגדיר את ה - DataField ואת ה - UniqeName כמו כן הגדרתי את המתודה למילוי ה - Combo (במקרה הזה מדובר באותה מתודה לכל ה - Combos)
צריך כמובן לזכור להוסיף את השורה הבאה
 

<%@ Register Assembly="WebApplication1" Namespace="Custom" TagPrefix="telerik" %>

 
קוד צד שרת:
 
 
המתודה שמביאה נתונים לגריד
 

protected void RadGrid1_NeedDataSource(object source, Telerik.Web.UI.GridNeedDataSourceEventArgs e)

{

    DataTable table = (DataTable)Session["table"];

    if (table == null)

    {

        table = CreateTable();

        Session["table"] = table;

    }

 

    RadGrid1.DataSource = table;

}

 

private static DataTable CreateTable()

{

    DataTable table = new DataTable();

    table.Columns.Add("a");

    table.Columns.Add("b");

    table.Columns.Add("c");

 

    table.Rows.Add("Day", "Private", "a");

    table.Rows.Add("Day", "Private", "b");

    table.Rows.Add("Day", "Public", "c");

    table.Rows.Add("Day", "Public", "d");

    table.Rows.Add("Evening", "Certificate", "e");

    table.Rows.Add("Evening", "Certificate", "f");

    table.Rows.Add("Evening", "Certificate", "g");

 

    return table;

}

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

protected void a_DDLFiltering(object sender, DDLFilterItemsEventArgs args)

{

    args.ComboBox.Items.Clear();

 

    List<string> list = new List<string>();

 

    DataTable table = (DataTable)Session["table"];

    for (int i = 0; i < table.Rows.Count; i++)

    {

        string text = table.Rows[i][args.ComboBox.DataValueField].ToString();

        if (!list.Contains(text))

        {

            list.Add(text);

        }

    }

 

    list.Sort();

    args.ComboBox.Items.AddRange(list.ConvertAll<RadComboBoxItem>(x => new RadComboBoxItem(x)));

 

    args.ComboBox.Items.Insert(0, new RadComboBoxItem(""));

}

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

Change ValidationGroup in client side (Java Script)

 

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

<input type="radio" name="valid" id="Radio1" value="group1" checked="checked" onclick="ChnageGropu(this)" />1

<input type="radio" name="valid" id="Radio2" value="group2" onclick="ChnageGropu(this)" />2

<br />

 

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

<asp:RequiredFieldValidator ID="rfv1" ValidationGroup="group1" runat="server"

    ControlToValidate="txt1" ErrorMessage="txt1" Text="*"></asp:RequiredFieldValidator>

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

<asp:RequiredFieldValidator ID="rfv2" ValidationGroup="group1" runat="server"

    ControlToValidate="txt2" ErrorMessage="txt2" Text="*"></asp:RequiredFieldValidator>

<br />

<br />

 

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

<asp:RequiredFieldValidator ID="rfv3" ValidationGroup="group2" runat="server"

    ControlToValidate="txt3" ErrorMessage="txt3" Text="*"></asp:RequiredFieldValidator>

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

<asp:RequiredFieldValidator ID="rfv4" ValidationGroup="group2" runat="server"

    ControlToValidate="txt4" ErrorMessage="txt4" Text="*"></asp:RequiredFieldValidator>

<asp:ValidationSummary ID="vs" runat="server" ShowMessageBox="true" ShowSummary="false"

    ValidationGroup="group1" />

<br />

<br />

 

<asp:Button ID="btn" Text="click" runat="server" ValidationGroup="group1" />

 
בזמן שינוי ה - Radio אנחנו רוצים לשנות את ה - ValidationGroup של הלחצן ושל ה - ValidationSummary.
 
כך נעשה זאת:
 

<script>

    function ChnageGropu(chk) {

        var btn = document.getElementById('btn');

 

        if (chk.id == "Radio1" && chk.checked) {

            Page_ValidationSummaries[0].validationGroup = "group1";

            btn.outerHTML = btn.outerHTML.replace('group2', 'group1');

        }

        else if (chk.id == "Radio2" && chk.checked) {

            Page_ValidationSummaries[0].validationGroup = "group2";

            btn.outerHTML = btn.outerHTML.replace('group1', 'group2');

        }

    }

</script>

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

protected void Page_Load(object sender, EventArgs e)

{

    if (Request["valid"] != null)

    {

        vs.ValidationGroup = Request["valid"];

        btn.ValidationGroup = Request["valid"];

    }

}

ArgumentOutOfRangeException - Value is not valid for OracleType: 0. Parameter name: oracleType

 

אם קבלתם את ההודעה הבאה:
Value is not valid for OracleType: 0. Parameter name: oracleType
 
מן הסתם כתבתם את הקוד הבא

OracleParameter param = new OracleParameter("name", 0);

 
מה שאתם צריכים לעשות זה אחד מהשניים
 

int num = 0;

OracleParameter param = new OracleParameter("name", num

 

OracleParameter param = new OracleParameter("name", Convert.ToInt32(0));

 
 
זה לא יעבוד
 

OracleParameter param = new OracleParameter("name", (int)0);

 
הסיבה לשגיאה זה הדרך שבה הם כתבו את ה - overload של הפונקציות, שימו לב: (הפונקציות איך שהם הוגדרו)
 

public OracleParameter(string name, object value);

public OracleParameter(string name, OracleType oracleType);

 
 
שני קריאות לפונקצייה
 

OracleParameter param = new OracleParameter("name", 0);

int num = 0;

OracleParameter param1 = new OracleParameter("name", num);

 
ואיך זה נראה כשפותחים Reflector
 

OracleParameter param = new OracleParameter("name", (OracleType)0);

int num = 0;

OracleParameter param1 = new OracleParameter("name", num);

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

object obj = 0;

OracleParameter param = new OracleParameter("name", obj);

 
 
ניסיתי לחקור קצת מדוע הערך 0 לא מתורגם ל object אלא ל - Enum ולא ממש הצלחתי להבין, אשמח לשמוע את הסיבה ממכם.
 
עריכה
תודה לסשה שהפנה אותי לדוקומנטציה של #C ששם כתוב
C# Language Specification, 6.1.3, Implicit Enumeration Conversions:
An implicit enumeration conversion permits the decimal-integer-literal 0 to be converted to any enum-type and to any nullable-type whose underlying type is an enum-type.
 
ותודה ללירן שהפנה אותי ל - MSDN ששם מתואר הבעייה והפיתרון.
 

מגזין שבועי נהדר (chief - magazine)

נרשמתי לפני כשנה לקבל את המגזין של חברת BOS (חברה לגיבוי והצלת נתונים)
 
אני ממליץ לכולם להירשם ולקרוא את המגזין.
 
(יש לינק בתחתית העמוד במגזין כדי להירשם לתפוצה)
Posted: Jan 07 2010, 08:42 PM by Shlomo | with 2 comment(s)
תגים:

חוויות ממפגש ה - User Group של קבוצת WPD

 

לשמוע ההרצאה מגדי זה חוויה, לשמוע הרצאה מסשה זה חוויה, לשמוע בערב אחד הרצאה גם מגדי וגם מסשה זה המקסימום שמפתח יכול לבקש לעצמו .
 
אז מה היה לנו. פבל פתח את המפגש עם דברי ברכה, לאחריו אלון תיאר בקצרה מה היה ב - PDC והסביר למה חשוב להגיע עד לוס אנג'לס לשמוע את ההרצאות אם אפשר לראות את כל ההרצאות של הכנס (בגדול זה הסתכם בלתקשר עם צוותי הפיתוח וקבלת מחשב נייד עם מסך מגע).
 
כאן התחילו התכנים הרציניים של הערב, למעשה גדי חילק את העולם לשלושה חלקים.
 
Heros - מתכנתי ++C
Mainstream - מתכנתי NET.
וכינוי שאני לא זוכר - VB6 וכו'
 
אני משתייך לקבוצה האמצעית (הייתי היחיד לדעתי - כולם היו מפתחי ++C) אבל מעניין אותי לשמוע ולהכיר את העולם האחר וטיפה לצלול לקרביים של הדברים.
 
גדי (שכמו שכתבתי זה פשוט חוויה לשמוע אותו) תיאר את העבודה שלו (אינסלטור)
ההרצאה שלו התמקדה ברצון שלנו שהאפליקציות שאנחנו כותבים יעבדו יותר טוב והסביר למה העולם מחפש את עצמו בכל מה שנוגע למקביליות - היו המון שקפים והסברים וממש נהניתי.
 
למעשה הסתבר שגדי חשב שסשה לא הגיע עדיין ולכן הוא העביר את ההרצאה בקצב איטי יחסית - וכשהוא סיים עם כל התאורייה והדיבורים על אינטל ומייקרוסופט וכל מיני אלגורתמאים - איך כותבים את המילה הזאת ? - (קנוט, או מישהו עם שם דומה) וכשהגיע החלק של תיאור התהליכים, פבל סמן לגדי שסשה מחכה ולא נשאר זמן, וחבל.
 
בהפסקה שאלתי את גדי שאלה (מסתבר שהיא טפשית) אבל אני מציין אותה בגלל שהתשובה הייתה גאונית.
אחד מאבני הבסיס של ההרצאה הייתה שקשה לכתוב אלגוריתמים שהם אכן מקביליים כי אין לנו כרגע את החומרה והטכנולוגיה המתאימה, מה שלא הבנתי - למה אלגוריתם שלכאורה הוא משהו לוגי קשור לאיזה חומרה נריץ את האלגוריתם, מה שגדי ענה לי היה פשוט גאוני, הוא תיאר לי אלגוריתם של אפיית עוגה ושאל שאלה פשוטה, האם האלגוריתם משתנה אם נאפה בתנור או שנחמם במיקרוגל ?
 
 
אחרי ההפסקה שהייתה קצרה (ולא טעימה - בזמן האחרון הבורקסים במפגשים הם על הפנים, אבל יש ירקות וזה מנחם) דבר סשה על החידושים של ++C ב - VS 2010 (סשה מאוד התלהב לדבר לפני קהל שחי ++C, למעשה הוא שאל מי לא מתכנת ב - ++C והייתי היחיד שהרים את היד).
 
דברנו על auto שזה כמו var שאנחנו מכירים,
על deceltype (או משהו כזה) שזה מין שיטה מוזרה להגדיר מה הטיפוס של משתנה - כלומר הם יכולים להגדיר שהטיפוס של משתנה A הוא כמו משתנה B, (כנראה שהם צריכים את ההגדרות הללו.)
בנוסף הם קבלו Lambda כמו שיש ב - #C אבל עם תחביר הרבה יותר מסובך.
לדעתי הוא הספיק להראות עוד משהו - אבל אני כבר לא זוכר.
 
 
אני ממליץ למפתחי NET (בתנאי שיש להם הבנה מינימלית ב - ++C) להגיע למפגשים, בנוסף במפגש הבא יהיה הגרלות של DevExpress על רשיונות למוצרים שלהם, ושווה להגיע.
Posted: Jan 07 2010, 12:10 AM by Shlomo | with no comments
תגים:, , ,

Integer out of range. 0 is not in the valid range of 1 to 1 (VSTO - Power Point)

 

התחלתי לעבוד על AddIn ל - Power Point והתחלתי לעשות את זה בעזרת VBA.
באמצע התהליך אמר לי שי שעדיף לי לעבוד עם VSTO, שמעתי בקולו ואני לא מתחרט - הכל הרבה יותר פשוט.
 
 
בכל מקרה שני דברים שיכולים להביא תועלת.
 
1. כשפותחים פרוייקט חדש זה נרשם לאירוע Startup ו - Shutdown.
אבל כדי לעבוד עם האלמנטים בעמוד צריך להרשם לאירועים אחרים שהראשון הוא  Application_AfterPresentationOpen ושם אפשר להתחיל לעבוד עם האלמנטים של presentation.Slides וכו'.
 
2. היות שבסופו של דבר מדובר ב - VB - כלומר אנחנו כותבים #C אבל ב - Power Point בעצמו הוא מודל אובייקטים של VB לכן אין כזה דבר מערך במקום 0, ואם יש לכם מצגת אחת ותכתבו את הקוד הבא
 
var slide = presentation.Slides[0];
 
תקבלו את השגיאה הבאה
 
System.Runtime.InteropServices.COMException (0x80048240): Slides (unknown member) : Integer out of range. 0 is not in the valid range of 1 to 1.
   at Microsoft.Office.Interop.PowerPoint.Slides.get_Item(Object Index)
 
ומה שצריך לעשות זה לגשת למקום 1 (אם יש לכם רק 1)

SDP (video) - ההקלטות

בלינק הבא תוכלו למצוא את כל ההקלטות של ההרצאות שהיו ב - SDP.
 
צפייה מהנה.
Posted: Jan 03 2010, 05:52 PM by Shlomo | with 2 comment(s)
תגים:, , ,

למה חשוב לבדוק IsValid בצד השרת כשמשתמשים עם validators (איך אפשר לעקוף (לפרוץ) את הבדיקות בצד הלקוח)

 

 (זהו פוסט ה - 200 שלי, ואני חושב שזהו הפוסט הראשון בבלוגייה של השנה הלועזית החדשה)
 
שיש לכם דף עם תיבת טקסט שמוצמד אליו RequiredFieldValidator ולחצן.
בזמן לחיצה כותבים על הדף את השעה הנוכחית.
 
הקוד נראה כך:
 
<asp:TextBox runat="server" ID="txt1" />

<asp:RequiredFieldValidator ErrorMessage="*" ControlToValidate="txt1"

runat="server" />

 

<asp:Button Text="text" runat="server" ID="btn" OnClick="btn_click" />

 צד השרת:
 
 
protected void btn_click(object sender, EventArgs e)

{

Response.Write(DateTime.Now.ToLongTimeString());

}

 
כשנריץ נראה את הדף הבא
 
validator1
 
 
אם ננסה ללחוץ על הלחצן ללא ערך בתיבת הטקסט לא תתבצע ריצה לשרת ואחנו נראה כוככבית ליד תיבת הטקסט
 
validator2
 
 
כעת נראה איך כל האקר מתחיל עוקף את הבדיקה.
 
בהנחה שיש לכם IE8 מותקן לכם IE Developer Toolar במידה ויש לכם IE7 תוכלו להוריד את זה מכאן
 
אחרי שתלחצו על הלחצן ותקבלו את הכוכבית - תפעילו את ה - Devloper Tool Bar (לחיצה על F12).
 
תקבלו את המסך הבא
 
IE Developer toolbar
 
תלחצו על החץ שמסומן באדום ותבחרו בכוכבית שמופיעה ליד תיבת הטקסט - כעת ה - tool bar יציג בצד שמאל את האלמנט הנבחר (הכוכבבית) ובצד ימין את כל הפרטים שלו.
תבחרו בטאב Attributes ותראו את כל המאפיינים
 
החלק השמאלי של ה - toolbar:
 
tool bar left
 
החלק הימני
 
 
tool  bar right
 
 
אחרי שבחרתם ב - attributes, תבחרו באלמנט שמסומן באדום ותלחצו על ה - X כדי למחוק אותו.
 
מה שזה יעשה - זה ימחק את הקריאה לפונקציית ה - JavsScript שבודקת האם יש ערך בתיבת הטקסט ותתבצע ריצה לשרת.
אמנם כשנחזור מהשרת נגלה שוב את הכוכבית מכיון שהבדיקה התבצעה גם בצד השרת - אבל היות שלא התייחסו לבדיקה - הקוד שלנו יתבצע ונראה את השעה.
 
not valid
 
 
היות שאחנו יודעים שהבדיקה מתבצעת בצד השרת - הדבר היחיד שצריך לעשות זה לשאול IsValid לפני הקוד שלנו
 
protected void btn_click(object sender, EventArgs e)

{

if (IsValid)

{

Response.Write(DateTime.Now.ToLongTimeString());

}

}

 
הערך של IsVAlid יהיה true רק עם כל ה - validators עברו בהצלחה.
 
אפשר להשתמש במאפיין הזה אחרי ה - Page_Load - כלומר בכל האירועים של הפקדים, אם נרצה להשתמש בו גם ב - Page_Load (או קודם) אנחנו צריכים לקרוא לפונקציית Validate לפני השימוש ב - IsValid.