我遇到了一个问题,我真的没想到会被耽误这么多时间,这让我感到疯狂
正如标题中所提到的,我需要两个DropDownLists,其中ToYears List的值从FromYear的选择开始:
的 FromYear
2000
2001年
2002
2003
2004年
的 ToYear
2002
2003
2004年
所以我尝试使用2< asp:dropdownlist >并在FromYear的SelectedIndexEvent期间更改选定的ToYear,但这会触发所选的FromYear事件,并且不会以某种方式再次触发。
现在我从Ajax Control Toolkit中找到CascadingDropDown并认为这可能是一件好事。但我不想调用Web服务,而是想在实际页面后面的代码中使用Method。
此外,应该在回发后记住选择 - 并且年份的范围根据后面的代码中的属性而变化。
我在某地读过autopostback不能与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;
}
事件处理程序:
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();
}
答案 0 :(得分:1)
填充DropDownList
控件可能听起来很简单吗?当你使用ASP.NET WebForms的默认行为时,它就是这样。但是,当您想要获取特定功能时,例如在WebForms中,尝试使用AJAX填充DropDownLists
时,您可能会遇到几个问题(这是一个真正的痛苦,我找到的唯一解决方案是禁用安全检查在页面<%@ Page EnableEventValidation="false"
)
供参考:
How to fill an asp:DropDown client side?
由于您使用WebForms可能最好的方法是使用粗略UpdatePanel
示例:
<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();
}
答案 1 :(得分:0)
最后我想出来并得到了 - 因为我认为这是一个很好的解决方案,因为它使我能够:
与我以前的方法的主要区别在于,我在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;
}
}
答案 2 :(得分:0)
这是HTML页面
在c#page背后的代码中
private void BindYearDropdown()
{
int year;
for (year = DateTime.Now.Year; year >= 2010 ; year--)
{
DDLYear.Items.Add(year.ToString());
}
}
以上代码适用于岁月病房