在我们的一个页面上,有一个下拉列表可以在预渲染时为其元素动态着色。但是,只要页面上的任何控件存在 ajax 回发,它就会立即失去所有样式(元素颜色)。我可以看出,在页面最初加载时以及每次进行任何 ajax 调用时都会调用预渲染。
<asp:DropDownList ID="DeviceObjectDDL" runat="server" Style="width: 350px;" OnPreRender="ColorDeviceListItems" AutoPostBack="true" OnSelectedIndexChanged="DeviceObjectDDL_SelectedIndexChanged" />
和
protected void ColorDeviceListItems(object sender, EventArgs e)
{
if (((DropDownList) sender).DataSource == null) return;
var disabledList = ((List<Device>) ((DropDownList) sender).DataSource).FindAll(d => !d.Active || !d.Visible);
foreach (var device in disabledList)
{
var item = ((DropDownList) sender).Items.FindByValue(device.ID.ToString());
if (item == null) continue;
if ((!device.Active) && (!device.Visible))
item.Attributes.CssStyle.Add("color", "Purple");
else
{
if (!device.Active)
item.Attributes.CssStyle.Add("color", "Blue");
if (!device.Visible)
item.Attributes.CssStyle.Add("color", "#8B0000");
}
}
}
在 ajax 请求期间调用 ColorDeviceListItems
方法时,sender
数据源为 null,因此它只是返回。
第一步
不使用 PreRender
事件,而是使用 DataBound
事件——这应该确保在数据源被查看状态。
<asp:DropDownList ID="DeviceObjectDDL" runat="server" Style="width: 350px;" OnDataBound="ColorDeviceListItems" AutoPostBack="true" OnSelectedIndexChanged="DeviceObjectDDL_SelectedIndexChanged" />
第 2 步
而不是使用发件人,这可能是导致回发发生的任何事情。使用控件本身的标识符,即; DeviceObjectDDL
代替。它已经正确标记为 runat="server"
,这应该允许您在后面的代码中直接访问它。
protected void ColorDeviceListItems(object sender, EventArgs e)
{
if (DeviceObjectDDL.DataSource == null) return;
var disabledList = ((List<Device>)(DeviceObjectDDL.DataSource).FindAll(d => !d.Active || !d.Visible);
foreach (var device in disabledList)
{
var item = DeviceObjectDDL.Items.FindByValue(device.ID.ToString());
if (item == null) continue;
if ((!device.Active) && (!device.Visible))
item.Attributes.CssStyle.Add("color", "Purple");
else
{
if (!device.Active)
item.Attributes.CssStyle.Add("color", "Blue");
if (!device.Visible)
item.Attributes.CssStyle.Add("color", "#8B0000");
}
}
}
在这种特定情况下,依赖发送者并不是最佳做法,因为无法保证发送者就是所需的控件。这在 AJAX 调用中很明显...
我是一名优秀的程序员,十分优秀!