如何从 jQuery (Sharepoint 2010) 调用服务器端事件?

How can I invoke a server-side event from jQuery (Sharepoint 2010)?

在我的 Sharepoint 2010 应用程序中,我使用 jQuery 处理大多数客户端事件。但是,为了将数据保存到 Sharepoint 列表,并使用该数据生成 PDF 文件,我想用 C# 处理服务器端。

我试过用这种方式调用 C# 事件:

0) 在我的项目的 *.ascx 文件中添加了一个 HTML 按钮:

<button type="button" name="saveData" id="saveData">Save Data</button>

1) 添加了 jQuery 以响应被单击的按钮(在同一个 *.ascx 文件中):

$("#saveData").click(function () {
      $('#hiddenSave').trigger('valuechanged');
  });

2) 在服务器端 C# 中创建了一个隐藏元素(在 *.ascx.cs 文件中):

HiddenField hiddenSave = null;

protected void Page_Load(object sender, EventArgs e)
{
    base.OnPreRender(e);

    hiddenSave = new HiddenField();
    hiddenSave.ID = "hiddenSave";
    hiddenSave.ValueChanged += new EventHandler(hiddenSave_ValueChanged);
    this.Controls.Add(hiddenSave);
}

protected void hiddenSave_ValueChanged(object sender, EventArgs e)
{
    GeneratePDF();
}

private void GeneratePDF()
{
    ;//bla
}

但我从未到达 "ValueChanged" 事件处理程序; $("#saveData").click() 触发,但不触发 hiddenSave_ValueChanged()。

所以我需要对此进行调整,还是需要一种完全不同的方法?如何在 Sharepoint 2010 应用程序中使用 jQuery 和 运行 server-side/C# 代码尽可能多地在客户端进行操作?

更新

更多细节,以及我尝试过的其他事情:我正在我的 *.ascx.cs 文件中动态地(在 C# 中)在 Sharepoint 页面上创建一个按钮:

Button btnSave = null;

protected void Page_Load(object sender, EventArgs e)
{
    base.OnPreRender(e);    

    this.Controls.Add(new LiteralControl("<br />"));
    btnSave = new Button();
    btnSave.ID = "btnSave";
    btnSave.Text = "Save the Data"; 
    btnSave.Click += new EventHandler(btnSave_Click);
    btnSave.Visible = false;
    this.Controls.Add(btnSave);
}

protected void btnSave_Click(object sender, EventArgs e)
{
    btnSave.Text = "You clicked me!"; 
    PostTravelData ptd = new PostTravelData();
}

我在客户端 jQuery *.ascx 文件中将它设置为在正确的时间可见:

$('#btnSave').show();

但是,单击按钮不会到达 btnSave_Click() 事件 - 那里的断点从未到达,按钮的文本也没有更改。为什么不呢?

即使我没有将按钮设置为不可见(注释掉 "btnSave.Visible = false;" 行),也没有达到点击处理程序...Page_Load() 来不及了吗?是否有我可以使用的早期页面事件?

我也尝试将其从 Page_Load() 移动到 OnPreRender(),如下所示:

protected void OnPreRender(EventArgs e)
{
    this.Controls.Add(new LiteralControl("<br />"));
    btnSave = new Button();
    btnSave.ID = "btnSave";
    btnSave.Text = "Save the Data";
    btnSave.Click += new EventHandler(btnSave_Click);
    //btnSave.Visible = false;
    this.Controls.Add(btnSave);
}

...(和 OnRender())但按钮甚至不显示...

并且,尝试不同的策略,我注释掉了动态创建服务器端代码并​​尝试附加到在 HTML(*.ascx 文件)中创建的按钮:

<button type="button" name="saveData" id="saveData" runat="server" onclick="saveData_Click">Save Data</button>

(通过添加 "runat server" 和 onclick 处理程序),然后添加此 "code-behind" (*.ascx.cs)):

protected void saveData_Click(object sender, EventArgs e)
{
    PostTravelData ptd = new PostTravelData();
    SaveToList(ptd);
    GeneratePDF(ptd);
}        

...但在 Mudville 中仍然没有乐趣 -- 未达到处理程序中的断点。

又一次尝试是:

在*.ascx:

<asp:Button runat="server" id="saveData" name="saveData" onclick="saveData_Click" Text="Bla" />

在代码隐藏中:

saveData.Click += saveData_Click;

已创建 "Bla" 按钮,但单击它未到达 "saveData_Click" 处理程序中的断点。

我什至从 here 中改编了一些代码,如下所示:

Button btnSave = null;

. . .

protected override void CreateChildControls()
{
    btnSave = new Button();
    btnSave.Width = new Unit(150, UnitType.Pixel);
    btnSave.Text = "Can you see me?";
    btnSave.Click += new EventHandler(btnSave_Click);
    Controls.Add(btnSave);
}

...但是当我单击按钮时我仍然没有到达 "protected void btnSave_Click(object sender, EventArgs e)" 处理程序。

肯定有办法在按钮服务器端获取句柄并对其进行操作(具体来说,响应其点击事件)...?!?

首先,据我所知,在ascx页面中没有隐藏输入类型的事件。如果您在 ascx 代码中创建使用 runat 服务器隐藏的输入类型,那么当您尝试添加此事件时,您会发现它不可用。但是,您可以模拟其他事件(例如 OnClick)以获得所需的结果。