3

私は本当に何時間も立ち往生することを期待していなかった問題で立ち往生していて、それは私を狂わせています

タイトルで述べたように、ToYearsリストにFromYearの選択で始まる値を持つ2つのDropDownListが必要です。


2000
年 から200120022003 2004
_

ToYear
2002
2003
2004

そこで、2 < asp: dropdownlist>を使用して、FromYearのSelectedIndexEvent中に選択したToYearを変更しようとしましたが、これにより、選択したFromYearイベントがトリガーされ、どういうわけか再び発生しませんでした。

今、私はAjax Control ToolkitからCascadingDropDownを見つけ、これは良いことかもしれないと思いました。しかし、Webサービスを呼び出したくはありません。代わりに、実際のページの背後にあるコードでメソッドを使用したいと思います。

また、ポストバック後に選択を覚えておく必要があります。年の範囲は、コードビハインドのプロパティによって異なります。

自動ポストバックがCascadingDropDownで機能しないことをどこかで読みました。

最もエレガントで簡単な解決策は何だと思いますか?

事前にどうもありがとうございました。

編集:私は私の投稿のいくつかの部分を投稿するつもりです-マークアップに役立つことを願っています:

    <asp:DropDownList AutoPostBack="True" ID="DropDownFromYear" runat="server"     OnSelectedIndexChanged="FromYearChanged" />
    <asp:Label ID="UntilLabel" runat="server" Text=" until " />
    <asp:UpdatePanel ID="ToYearUpdatePanel" runat="server" style="display: inline-block;">
        <ContentTemplate>
            <asp:DropDownList AutoPostBack="true" ID="DropDownToYear" runat="server" OnSelectedIndexChanged="ToYearChanged" />
        </ContentTemplate>
        <Triggers>
            <asp:AsyncPostBackTrigger ControlID="DropDownFromYear" EventName="SelectedIndexChanged" />
        </Triggers>
    </asp:UpdatePanel>

CodeBehind(OnInitから呼び出されます):

    private void InitializeDropDownYears()
    {

        //Calculate the YearMin YearMax Properties
        CalculateYearMinMax();

        int adaptedFromYear = 0, adaptedToYear = 0;

        //get the previously selected Years
        if (DropDownToYear.SelectedItem != null) adaptedToYear = int.Parse(DropDownToYear.SelectedValue);
        if (DropDownFromYear.SelectedItem != null) adaptedFromYear = int.Parse(DropDownFromYear.SelectedValue);

        //check the minimum year constraints 2005 was selected but minYear is 2010 -> adpated is set to 2010
        if (YearMin > adaptedFromYear || adaptedFromYear == 0) adaptedFromYear = YearMin;
        if (YearMax < adaptedToYear || adaptedToYear == 0) adaptedToYear = YearMax;

        //check the 5 year range constraint
        if ((YearMax - YearMin) > 5)
        {
            adaptedFromYear = DateTime.Now.Year - 2;
            adaptedToYear = DateTime.Now.Year + 2;
        }

        Dictionary<string, string> toYears = new Dictionary<string, string>();
        Dictionary<string, string> fromYears = new Dictionary<string, string>();

        for (int tempYear = YearMin; tempYear <= YearMax; tempYear++)
        {
            fromYears.Add(tempYear.ToString(), tempYear.ToString());
            if (tempYear >= adaptedFromYear)
            {
                toYears.Add(tempYear.ToString(), tempYear.ToString());
            }
        }

        DropDownFromYear.DataSource = fromYears;
        DropDownFromYear.DataValueField = "Key";
        DropDownFromYear.DataTextField = "Value";
        DropDownFromYear.SelectedValue = adaptedFromYear.ToString();
        DropDownFromYear.DataBind();

        DropDownToYear.DataSource = toYears;
        DropDownToYear.DataValueField = "Key";
        DropDownToYear.DataTextField = "Value";
        DropDownToYear.SelectedValue = adaptedToYear.ToString();
        DropDownToYear.DataBind();
        if(!IsPostBack)
        {
            SelectedFromYear = adaptedFromYear;
            SelectedToYear = adaptedToYear;
        }
    }

    private void CalculateYearMinMax()
    {
        IList<Task> taskList = CurrentLicense.TaskList;

        List<DateTime> startDates = taskList.Select(task => task.StartDate).ToList();
        YearMin = startDates.Min(date => date).Year;

        List<DateTime> endDates = taskList.Select(task => task.EndDate).ToList();
        YearMax = endDates.Max(date => date).Year;
    }

EventHandler:

    protected void FromYearChanged(object sender, EventArgs e)
    {
        SelectedFromYear = int.Parse(DropDownToYear.SelectedValue);
        SelectedToYear = int.Parse(DropDownFromYear.SelectedValue);
        if (SelectedFromYear > SelectedToYear)
        {
            SelectedToYear = SelectedFromYear;
        }
        UpdateGanttTables();
    }

    protected void ToYearChanged(object sender, EventArgs e)
    {
        SelectedFromYear = int.Parse(DropDownToYear.SelectedValue);
        SelectedToYear = int.Parse(DropDownFromYear.SelectedValue);
        UpdateGanttTables();
    }
4

3 に答える 3

1

コントロールの入力DropDownListは簡単に聞こえるかもしれませんね。それは、ASP.NETWebFormsのデフォルトの動作を使用する場合です。ただし、特定の機能を取得する場合、たとえばWebFormsでAJAXを使用して入力しようとすると、いくつかの問題が発生する可能性がありDropDownListsます(これは非常に苦痛であり、私が見つけた唯一の解決策は、ページのセキュリティチェックを無効にすることです<%@ Page EnableEventValidation="false") 。

参考のために:

asp:DropDownクライアント側を埋める方法は?

WebFormsを使用しているので、おそらく最良の方法はグロスを使用することですUpdatePanel

例:

結果

ここに画像の説明を入力してください

ASPXマークアップ

    <asp:ScriptManager runat="server" ID="sm" />
    <asp:UpdateProgress runat="server" AssociatedUpdatePanelID="updatePanel" DisplayAfter="0" DynamicLayout="true">
        <ProgressTemplate>
            Working...
        </ProgressTemplate>
    </asp:UpdateProgress>
    <asp:UpdatePanel runat="server" ID="updatePanel">
        <ContentTemplate>
            <div>
                <asp:Label ID="Label1" Text="From" runat="server" AssociatedControlID="from" />
            </div>
            <div>
                <asp:DropDownList runat="server" ID="from" AutoPostBack="true" CausesValidation="false" OnSelectedIndexChanged="from_SelectedIndexChanged">
                </asp:DropDownList>
            </div>
            <div>
                <asp:Label ID="Label2" Text="To" runat="server" AssociatedControlID="to" />
            </div>
            <div>
                <asp:DropDownList runat="server" ID="to" />
            </div>
        </ContentTemplate>
    </asp:UpdatePanel>

背後のページコード

    private const int MaxYear = 2030;
    private const int MinYear = 1959;

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!this.IsPostBack)
        {
            var fromRange = Enumerable.Range(MinYear, MaxYear - MinYear);

            this.from.DataSource = fromRange;
            this.from.DataBind();
        }
    }

    protected void from_SelectedIndexChanged(object sender, EventArgs e)
    {
        var selectedYear = Convert.ToInt32(this.from.SelectedValue);
        var toRange = Enumerable.Range(selectedYear, MaxYear - selectedYear);

        this.to.DataSource = toRange;
        this.to.DataBind();
    }

このサンプルを参照用にGitHubにアップロードしました

于 2012-10-01T18:47:40.480 に答える
0

結局、私はそれを理解し、得ました-それは私が次のことを可能にするので、私は素晴らしい解決策だと思います:

  • 最初に両方のDDLにデータを入力します
  • 両方のDDLでアイテムを事前選択します
  • 引き続きページでEnableEventValidation="true"を使用してください
  • DataBind()を呼び出すだけでDDLを更新できます。それらの上に

以前のアプローチとの主な違いは、OnDataBindingイベント中にDDLにデータを入力することです。したがって、PageLoad中にDataBind()を実行すると、自動的に発生します。私が最初に確認しなければならないのは、私の情報を含む辞書に記入することだけです。

FromYearsDDLのselectionChangeEventからToYearsDDLを更新する場合は、ToYearsDDLのデータを更新し、ToYearsDDL.DataBind();を呼び出すだけです。

これが同じ壁にぶつかる他の誰かを助けることを願っています!

マークアップは次のとおりです。

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="LinkedDropDownsBound.aspx.cs"
    Inherits="ASP.Net_Spielwiese.LinkedDropDownsBound"  EnableEventValidation="true" %>

<!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">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server">
    </asp:ScriptManager>
    <div>
        <asp:UpdatePanel runat="server" ID="updatePanel">
            <ContentTemplate>
                <div>
                    <asp:Label ID="FromLabel" Text="From" Enabled="false" runat="server"  />
                </div>
                <div>
                    <asp:DropDownList runat="server" ID="FromYearsDDL" AutoPostBack="true" CausesValidation="false" OnDataBinding="DDLFromDataBind"
                        OnSelectedIndexChanged="DDLFromSelectedIndexChanged">
                    </asp:DropDownList>
                </div>
                <div>
                    <asp:Label ID="ToLabel" Text="To" Enabled="false" runat="server" />
                </div>
                <div>
                    <asp:DropDownList runat="server" ID="ToYearsDDL" AutoPostBack="true" CausesValidation="false" OnDataBinding="DDLToDataBind"
                        OnSelectedIndexChanged="DDLToSelectedIndexChanged"/>
                </div>
            </ContentTemplate>
        </asp:UpdatePanel>
    </div>
    </form>
</body>
</html>

そして、ここにコードがあります:

public partial class LinkedDropDownsBound : System.Web.UI.Page
{
    public Dictionary<String, Boolean> FromYears
    {
        get
        {
            if (ViewState["FromYears"] == null)
            {
                ViewState["FromYears"] = new Dictionary<String, Boolean>();
            }
            return ViewState["FromYears"] as Dictionary<String, Boolean>;
        }
        set
        {
            ViewState["FromYears"] = value;
        }
    }
    public Dictionary<String, Boolean> ToYears
    {
        get
        {
            if (ViewState["ToYears"] == null)
            {
                ViewState["ToYears"] = new Dictionary<String, Boolean>();
            }
            return ViewState["ToYears"] as Dictionary<String, Boolean>;
        }
        set
        {
            ViewState["ToYears"] = value;
        }
    }

    public int MinYear = 1975;
    public int MaxYear = 2015;


    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            InitFromYears();
            InitToYears();
            DataBind();
        }
    }

    private void InitFromYears()
    {
        FromYears = new Dictionary<string, bool>();
        IEnumerable<int> fromRange = Enumerable.Range(MinYear, MaxYear - MinYear);

        foreach (var fromYear in fromRange)
        {
            FromYears.Add(fromYear.ToString(), fromYear == (DateTime.Now.Year - 2));
        }
    }

    private void InitToYears()
    {
        ToYears = new Dictionary<string, bool>();
        //get the selected FromYear Value
        int minToYear = Convert.ToInt32(FromYears.FirstOrDefault(dict => dict.Value).Key);
        //make sure ToYears is at least FromYears
        if (minToYear < Convert.ToInt32(FromYears.Min(k => k.Key)))
        {
            minToYear = Convert.ToInt32(FromYears.Min(k => k.Key));
        }
        IEnumerable<int> toRange = Enumerable.Range(minToYear, MaxYear - minToYear);
        foreach (var toYear in toRange)
        {
            ToYears.Add(toYear.ToString(), toYear == (DateTime.Now.Year + 2));
        }
    }

    protected void DDLFromDataBind(object sender, EventArgs e)
    {
        FromYearsDDL.DataSource = FromYears;
        FromYearsDDL.DataValueField = "Key";
        FromYearsDDL.DataTextField = "Key";
        FromYearsDDL.SelectedValue = FromYears.FirstOrDefault(y => y.Value).Key;
    }

    protected void DDLFromSelectedIndexChanged(object sender, EventArgs e)
    {
        //update the FromYear Dictionary
        var tempDictionary = FromYears.ToDictionary(fromYear => fromYear.Key, fromYear => fromYear.Key.Equals(FromYearsDDL.SelectedValue));
        FromYears = tempDictionary;

        //Call Bind on the ToYear DDL
        ToYearsDDL.DataBind();

        //do my other update stuff here
        FromLabel.Text = FromYearsDDL.SelectedValue;
        ToLabel.Text = ToYearsDDL.SelectedValue;
    }

    protected void DDLToSelectedIndexChanged(object sender, EventArgs e)
    {
        //do my other update stuff here
        FromLabel.Text = FromYearsDDL.SelectedValue;
        ToLabel.Text = ToYearsDDL.SelectedValue;
    }

    protected void DDLToDataBind(object sender, EventArgs e)
    {
        InitToYears();
        ToYearsDDL.DataSource = ToYears;
        ToYearsDDL.DataValueField = "Key";
        ToYearsDDL.DataTextField = "Key";
        ToYearsDDL.SelectedValue = ToYears.FirstOrDefault(y => y.Value).Key;
    }
}
于 2012-10-02T15:28:17.883 に答える
0

これはHTMLページです

C#ページの背後にあるコード

private void BindYearDropdown()
        {
            int year;

            for (year = DateTime.Now.Year; year >= 2010 ; year--)
            {
                DDLYear.Items.Add(year.ToString());
            }
        }

上記のコードは数年前のワード用です

于 2016-02-24T15:00:56.347 に答える