asp:异步的DataGrid可见性?
Posted
技术标签:
【中文标题】asp:异步的DataGrid可见性?【英文标题】:asp:DataGrid visibility with async? 【发布时间】:2015-10-03 06:38:16 【问题描述】:.NET 4.5.2,Windows 8.1 x64 上的 IIS 8.5。我在 /localhost/ 有一个 ASP.NET 网站。
我在这里遇到了一个真正的异步谜题,我已经为此苦苦挣扎了两天。
我正在修改一些长期运行的报告以使其异步,但我可以用非常简单的代码来证明我的问题。
我的页面上有一个 asp:DataGrid,我最初设置为 visible="false"。只有当它被填充时它才应该是可见的。我的问题是,如果填充它的代码是异步的,我看不到网格!
这是标记:
<body>
<form runat="server">
<asp:datagrid ID="grid" visible="false" Runat="server"></asp:datagrid>
</form>
</body>
在代码隐藏中,此代码有效:
void Page_Load()
grid.DataSource = new Dictionary<string, string>()
"col1", "value1"
;
grid.DataBind();
grid.Visible = true;
现在,如果我进行两项更改:
将 Async="True" 添加到 @Page 指令 用这个替换 Page_Load
void Page_Load()
this.RegisterAsyncTask(new PageAsyncTask(async () =>
grid.DataSource = new Dictionary<string, string>()
"col1", "value1"
;
grid.DataBind();
grid.Visible = true;
));
网格未渲染。请注意,即使委托中没有等待,我也使用了 async 关键字。我尝试了几件事,结果都一样:
-
添加等待 Task.Delay(...)
删除 async 关键字并返回 Task.FromResult(0)
我已经覆盖并检测了页面生命周期事件,以查看网格何时填充以及其可见性如何变化。这是我看到的输出:
OnPreInit: Visible=False Rows=0 Thread=63
OnInit: Visible=False Rows=0 Thread=63
OnInitComplete: Visible=False Rows=0 Thread=63
OnPreLoad: Visible=False Rows=0 Thread=63
OnLoad: Visible=False Rows=0 Thread=63
OnLoadComplete: Visible=False Rows=0 Thread=63
OnPreRender: Visible=False Rows=0 Thread=63
Async 1: Visible=False Rows=0 Thread=63
Async 2: Visible=True Rows=1 Thread=63
OnPreRenderComplete: Visible=True Rows=1 Thread=63
OnSaveStateComplete: Visible=True Rows=1 Thread=63
Render 1: Visible=True Rows=1 Thread=63
Render 2: Visible=True Rows=1 Thread=63
“Async 1”和“2”位于委托内网格填充的两侧。您可以看到网格有一行并且它的可见性变为真实,但它没有被渲染。如果我用我的第一个代码示例同步填充网格,一切都很好。
另一个注意事项:我可以将网格包含在另一个控件中以使其工作:
<body>
<form runat="server">
<div id="container" visible="false" runat="server">
<asp:datagrid ID="grid" Runat="server"></asp:datagrid>
</div>
</form>
</body>
似乎是 asp:datagrid 本身上的 visible="false" 搞砸了。
我做错了什么?
【问题讨论】:
我认为这个问题源于 visible="false" 控件如何被“丢弃”,可以这么说。你可能会用 display:none; 做一些丑陋的工作。或者将 visible="true" 设置为默认值,如果它没有被渲染绑定,则将其设置为 false 实际上,可能是行在您更改之前继承了可见性吗? @PRATANTIA:有趣的想法 - 我添加了代码来设置 DataGridItem 及其所有 TableCells 可见,我很欣慰地说我得到了相同的结果。 做一些研究得到了***.com/questions/1598361/…,这表明带有 visible = false 的控件将在页面加载时停止处理,并且不会达到预渲染/渲染。 @PRATANTIA:谢谢。我通过将同步代码放在 OnPreRender 之后进行了更多测试,它仍然可以工作,而异步则不能,它同时运行。还在挖…… 【参考方案1】:尝试将 Grid 放在 UpdatePanel 中,并在 UpdatePanel 的 OnLoad 事件上调用异步方法(以加载 Grid 中的数据并管理其可见性)
【讨论】:
【参考方案2】:假设RegisterAsyncTask
返回一个promise,试试
this.RegistreAsyncTask(
async () =>
return new Dictionary<string, string>()
"col1", "value1"
;
).then(dataSource => grid.DataSource = dataSource; grid.visible = true)
async
的想法在不同的后台线程中运行,Promise
在UI thread
中得到解决(与类似的 android 概念相关)
【讨论】:
以上是关于asp:异步的DataGrid可见性?的主要内容,如果未能解决你的问题,请参考以下文章
在鼠标悬停时更改 DataGrid ScrollBar 的可见性?
RowDoubleClick 上的 DataGrid RowDetails 可见性
如何将 WPF DataGrid DataColumns 可见性绑定到 UserControl 的 ViewModel 上的属性?