以下是它的工作原理:
过滤器Web部件将数据行发送到页面上的所有其他Web部件。 它的控件在加载时呈现,呈现控件选择将哪一行发送回页面上的其他webpart。
这导致第一页上的问题加载,其他webparts在加载完成之前将从提供者请求该行,因此还没有提供信息。
唯一的解决方案(实际上是丑陋,缓慢和可怕)是运行将在webpart的构造函数中使用的控件类中运行的所有代码,并使用它来预测控件将具有哪些值第一次运行。这也导致了一大堆我需要避免的部署问题。
这是webpart代码:
public class FilterProjectHeader : WebPart, IWebPartRow
{
// Visual Studio might automatically update this path when you change the Visual Web Part project item.
private const string _ascxPath = @"[link goes here]";
public DataRowView data;
public DataTable table;
private FilterProjectHeaderUserControl control;
public FilterProjectHeader()
{
//Code I want to avoid using:
//var web = SPContext.Current.Web;
//table = web.Lists["foo"].Items.GetDataTable();
//data = foo();
}
protected override void CreateChildControls()
{
control = Page.LoadControl(_ascxPath) as FilterProjectHeaderUserControl;
control.provider = this;
Controls.Add(control);
}
public PropertyDescriptorCollection Schema
{
get
{
return TypeDescriptor.GetProperties(table.DefaultView[0]);
}
}
[ConnectionProvider("Row")]
public IWebPartRow GetConnectionInterface()
{
return this;
}
public void GetRowData(RowCallback callback)
{
callback(data);
}
}
对于控件:
public partial class FilterProjectHeaderUserControl : UserControl
{
public FilterProjectHeader provider { get; set; }
private String _selectedValue;
//Both OnLoad and OnInit have the same result.
protected override void OnInit(EventArgs e)
{
//This is what gets run the first time:
if (!IsPostBack)
{
//Code here finds data then sends it back to webpart like this:
//All of the code in this method definitely does run; I have stepped
//through it and it works but it seems to happen too late to have any
//effect.
provider.data = item;
provider.table = profilesTable;
}
}
protected void filterDropDown_SelectedIndexChanged(object sender, EventArgs e)
{
//Post back method code exempted... it works.
provider.data = item;
provider.table = profilesTable;
}
答案 0 :(得分:0)
因此,经过大量的时间处理后,我发现问题实际上是微软建议做的最佳实践(他们说总是使用CreateChildControls将控件加载到页面上)。
CreateChildControls在第一次加载页面时在OnLoad之后运行,但在重新发布时运行在OnLoad上。 这就是为什么它适用于转发,但不适用于首页加载。
将CreateChildControls切换为OnInit可以解决问题,因为OnInit将始终在OnLoad之前运行。