我正在使用Web表单,并且具有一系列遵循相同模式的输入字段。他们有一个标签来显示文本,只需单击一个按钮即可切换到文本字段,从而保存文本。
我只希望用户一次编辑一个字段,这样,如果他们开始编辑第二个字段,则第一个字段将被保存。
我的代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace vk_HVK_Web.User_Controls
{
[ValidationProperty("Text")]
[ToolboxData("<{0}:EditableLabel runat=server></{0}:EditableLabel>")]
public partial class EditableLabel : System.Web.UI.UserControl
{
public event EventHandler OnSave;
public static EditableLabel CurrentEditing;
public string DisplayText { get
{
return this.Text.ToUpper();
}
}
public string Text { get => txtInput.Text; set => txtInput.Text = value; }
public bool Editable { get => txtInput.Visible; set => txtInput.Visible = value; }
protected void Page_PreRender(object sender, EventArgs e)
{
if (Editable)
{
txtInput.Visible = true;
lblText.Visible = false;
btnEditSave.CssClass = "fas fa-save";
sectionEditable.CssClass = "col";
}
else
{
lblText.Visible = true;
txtInput.Visible = false;
btnEditSave.CssClass = "fas fa-pencil-alt";
sectionEditable.CssClass = "col col-form-label text-left";
}
lblText.Text = DisplayText;
}
protected void Page_Load(object sender, EventArgs e)
{
}
protected void txtInput_TextChanged(object sender, EventArgs e)
{
this.Text = txtInput.Text;
}
protected void btnEditSave_Click(object sender, EventArgs e)
{
if (Editable)
{
Save();
} else
{
Edit();
}
}
public void Edit()
{
if (CurrentEditing != null && CurrentEditing != this && CurrentEditing.Editable)
CurrentEditing.Save();
CurrentEditing = this;
Editable = true;
}
public void Save()
{
Editable = false;
if (OnSave != null)
OnSave(this, EventArgs.Empty);
}
}
}
我不认为设计中的代码很有用,但无论如何这里都是这样:
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="EditableLabel.ascx.cs" Inherits="vk_HVK_Web.User_Controls.EditableLabel" %>
<div class="row">
<div class="col-12">
<div class="row">
<div class="col-4 col-form-label text-right">Start Date: </div>
<asp:Panel runat="server" id="sectionEditable">
<asp:Label ID="lblText" runat="server" Text="" ></asp:Label>
<asp:TextBox Visible="false" ID="txtInput" runat="server" Text="" OnTextChanged="txtInput_TextChanged" CssClass="form-control" ></asp:TextBox>
</asp:Panel>
<div class="col-4 col-form-label">
<span><asp:LinkButton ID="btnEditSave" runat="server" OnClick="btnEditSave_Click" /></span>
</div>
</div>
</div>
</div>
如您所见,当他们单击按钮进行编辑时,它要做的第一件事是检查是否正在编辑其他内容,如果要保存,则进行保存。 save方法会更改组件的状态,并使其不再可编辑。
就目前而言,单独进行切换非常有效,但是调用静态变量的Save()
方法似乎根本不会影响其状态。
我们将不胜感激。我是Webforms的新手,所以如果我做错状态管理,请告诉我如何正确执行。谢谢。
答案 0 :(得分:0)
好的,这花了我2天的时间,但是我知道对ASP.NET有很多了解。
我的解决方案是2倍,首先是由于某种原因,我认为静态生存期是针对每个用户的,就像在前端框架中那样,并非如此。这意味着它已在所有用户和所有页面之间共享。不好吧?
由于我想每页使用它,因此我使用了ViewState
。用户控件有自己的ViewState
,我需要Page
,但是它是protected
,因此无法使用。
我使用以下扩展程序类公开了ViewState
:
public static class SharedViewStateExtension
{
public static StateBag GetProtectedViewState(this Page page)
{
var viewStateField = typeof(Page).GetProperty("ViewState", BindingFlags.NonPublic | BindingFlags.Instance);
return (StateBag) viewStateField.GetValue(page);
}
}
当然,无论您放入ViewState中的任何内容都必须可序列化,而我无法做到这一点。因此,我将EditableLabels存储在会话级词典中,其中的键是保存在ViewState中的GUID。
第二个问题是ControlFromPriviousPageLoad != ControlFromNextPageLoad
。每次页面加载都会生成新组件。取而代之的是,我还是比较每个页面应该唯一的ID。
我知道所有这些听起来很讨厌,但是ASP.NET令人作呕,所以就让我们离开吧。