【发布时间】:2012-03-22 01:40:29
【问题描述】:
我正在尝试编写一个 webpart,它基本上从列表中提取数据并将其显示给用户。有一个专题新闻列表,其中一列包含图像的 URL。 Web 部件应获取 3 个最新的专题新闻项目并在页面上创建三个图像控件。这些图像控件可以通过单击按钮 1、2、3 滚动。 (即点击2会将图片1和图片3的Visible属性设置为false)。
我已经设法在这里实现了 AJAX,但现在我正在尝试使用 AJAX 控件工具包中的 UpdatePanelAnimationExtender。
我已按照有关如何使用该工具包、将其添加到 GAC、添加安全程序集等的所有说明进行操作,并且已经克服了除此之外的所有错误:
“页面不能为空。请确保此操作是在 ASP.NET 请求的上下文中执行的”
我的完整代码如下:
using System; using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.WebControls;
using System.Web.Extensions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using System.ComponentModel;
using AjaxControlToolkit;
namespace FeatureNewsWebpartFeature {
[Guid("7ad4b959-d494-4e85-b164-4e4231692b8b")]
public class FeatureNewsWebPart : Microsoft.SharePoint.WebPartPages.WebPart
{
private bool _error = false;
private string _listName = null;
private string _imageColumn = null;
Image image1;
Image image2;
Image image3;
UpdatePanelAnimationExtender upAnimator;
[Personalizable(PersonalizationScope.Shared)]
[WebBrowsable(true)]
[System.ComponentModel.Category("List Connection Settings")]
[WebDisplayName("List Name")]
[WebDescription("Enter the name of the news list")]
public string ListName
{
get
{
if (_listName == null)
{
_listName = "News";
}
return _listName;
}
set { _listName = value; }
}
[Personalizable(PersonalizationScope.Shared)]
[WebBrowsable(true)]
[System.ComponentModel.Category("List Connection Settings")]
[WebDisplayName("Image Column Name")]
[WebDescription("Enter the column name of the ArtfulBits Image Upload column")]
public string ImageUrlColumn
{
get
{
if (_imageColumn == null)
{
_imageColumn = "Feature Image";
}
return _imageColumn;
}
set { _imageColumn = value; }
}
public FeatureNewsWebPart()
{
this.ExportMode = WebPartExportMode.All;
}
/// <summary>
/// Create all your controls here for rendering.
/// Try to avoid using the RenderWebPart() method.
/// </summary>
protected override void CreateChildControls()
{
if (!_error)
{
try
{
base.CreateChildControls();
//Create script manager
if (ToolkitScriptManager.GetCurrent(this.Page) == null)
{
ToolkitScriptManager scriptHandler = new ToolkitScriptManager();
scriptHandler.ID = "scriptHandler";
scriptHandler.EnablePartialRendering = true;
this.Controls.Add(scriptHandler);
}
//Create update panel
System.Web.UI.UpdatePanel imageUpdatePanel = new System.Web.UI.UpdatePanel();
imageUpdatePanel.ID = "imageUpdatePanel";
imageUpdatePanel.UpdateMode = UpdatePanelUpdateMode.Conditional;
this.Controls.Add(new LiteralControl("<div id=\"updateContainer\">"));
this.Controls.Add(imageUpdatePanel);
this.Controls.Add(new LiteralControl("</div>"));
//Make SPSite object and retrieve the three most recent feature news items
SPSite site = SPContext.Current.Site;
using (SPWeb web = site.OpenWeb())
{
SPList oList = web.Lists[ListName];
SPQuery oQuery = new SPQuery();
oQuery.RowLimit = 3;
oQuery.Query = "<OrderBy>" +
"<FieldRef Name='Modified' Ascending='False' /></OrderBy>" +
"<Where>" +
"<Eq>" +
"<FieldRef Name='ContentType' />" +
"<Value Type='Choice'>Feature News Item</Value>" +
"</Eq>" +
"</Where>";
oQuery.ViewFields = string.Concat(
"<FieldRef Name='Feature_x0020_Image' />" +
"<FieldRef Name='Feature_x0020_Order' />");
image1 = new Image();
image2 = new Image();
image3 = new Image();
//For each item, extract image URL and assign to image object
SPListItemCollection items = oList.GetItems(oQuery);
foreach (SPListItem oListItem in items)
{
string url = oListItem["Feature_x0020_Image"].ToString();
url = url.Substring(url.IndexOf("/Lists"));
url = url.Remove(url.IndexOf(";#"));
switch (oListItem["Feature_x0020_Order"].ToString())
{
case "1":
image1.ImageUrl = url;
break;
case "2":
image2.ImageUrl = url;
break;
case "3":
image3.ImageUrl = url;
break;
default:
//ERROR
break;
}
}
if (!(Page.IsPostBack))
{
image1.Visible = true;
image2.Visible = false;
image3.Visible = false;
}
imageUpdatePanel.ContentTemplateContainer.Controls.Add(image1);
imageUpdatePanel.ContentTemplateContainer.Controls.Add(image2);
imageUpdatePanel.ContentTemplateContainer.Controls.Add(image3);
//Create animation for update panel
upAnimator = new UpdatePanelAnimationExtender();
upAnimator.ID = "upAnimator";
upAnimator.TargetControlID = imageUpdatePanel.ID;
const string xml = "<OnUpdating>" +
"<Parallel duration=\".25\" Fps=\"30\">" +
"<FadeOut AnimationTarget=\"updateContainer\" minimumOpacity=\".2\" />" +
"</OnUpdating>" +
"<OnUpdated>" +
"<FadeIn AnimationTarget=\"updateContainer\" minimumOpacity=\".2\" />" +
"</OnUpdated>";
Animation.Parse(xml, upAnimator);
this.Controls.Add(upAnimator);
Button b1 = new Button();
b1.ID = "b1i";
b1.Click += new EventHandler(b1_Click);
b1.Text = "Image 1";
Button b2 = new Button();
b2.ID = "b2i";
b2.Click += new EventHandler(b2_Click);
b2.Text = "Image 2";
Button b3 = new Button();
b3.ID = "b3i";
b3.Click += new EventHandler(b3_Click);
b3.Text = "Image 3";
this.Controls.Add(b1);
this.Controls.Add(b2);
this.Controls.Add(b3);
AsyncPostBackTrigger tr1 = new AsyncPostBackTrigger();
tr1.ControlID = b1.ID;
//tr1.EventName = "Click";
imageUpdatePanel.Triggers.Add(tr1);
AsyncPostBackTrigger tr2 = new AsyncPostBackTrigger();
tr2.ControlID = b2.ID;
//tr2.EventName = "Click";
imageUpdatePanel.Triggers.Add(tr2);
AsyncPostBackTrigger tr3 = new AsyncPostBackTrigger();
tr3.ControlID = b3.ID;
//tr3.EventName = "Click";
imageUpdatePanel.Triggers.Add(tr3);
}
}
catch (Exception ex)
{
HandleException(ex);
}
}
}
void b1_Click(object sender, EventArgs e)
{
image1.Visible = true;
image2.Visible = false;
image3.Visible = false;
}
void b2_Click(object sender, EventArgs e)
{
image1.Visible = false;
image2.Visible = true;
image3.Visible = false;
}
void b3_Click(object sender, EventArgs e)
{
image1.Visible = false;
image2.Visible = false;
image3.Visible = true;
}
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
}
protected override void Render(HtmlTextWriter writer)
{
base.Render(writer);
}
/// <summary>
/// Ensures that the CreateChildControls() is called before events.
/// Use CreateChildControls() to create your controls.
/// </summary>
/// <param name="e"></param>
protected override void OnLoad(EventArgs e)
{
if (!_error)
{
try
{
base.OnLoad(e);
this.EnsureChildControls();
// Your code here...
}
catch (Exception ex)
{
HandleException(ex);
}
}
}
/// <summary>
/// Clear all child controls and add an error message for display.
/// </summary>
/// <param name="ex"></param>
private void HandleException(Exception ex)
{
this._error = true;
this.Controls.Clear();
this.Controls.Add(new LiteralControl(ex.Message));
}
} }
【问题讨论】:
-
我知道这也不是实现我想要做的事情的最佳方式。理想情况下,我想使用 jQuery 在客户端对图像进行动画处理,以完全避免回发到服务器更改图像。我的问题是我不知道如何将 jQuery 插入到 MOSS 2007 Web 部件中,然后引用图像/动画它们.. 嗯...
-
您需要查看用于 jQuery 的 SPServices 插件来回答您的评论。我们有一个部分可以做到这一点:从列表中读取网站的头条新闻,并在它们之间的延迟计时器上设置动画。我敢肯定有这方面的网络示例;我怀疑创建它的团队中的人是从零开始的。
-
另外,页面不能为空很可能来自 scriptmanager 调用。您可能必须延迟到 prerender 才能拥有一个真正的 Page 实例。 CreateChildControls 在很多地方都被调用,也许由于某种原因,Page 在被调用的时候并不是一个真实的对象。 >> if (ToolkitScriptManager.GetCurrent(this.Page) == null)
-
谢谢 Erik,我会尝试将工具包放在 OnPreRender 中,看看它是否能解决问题,然后查看 SPServices。
标签: asp.net sharepoint sharepoint-2007 moss