Closed MG1376 closed 5 months ago
EditItemTemplate will not add ChildControl to GridViewRow until its RenderFragment\<TItem> is actually executed. FindControl must wait until the addition is completed before it can be used.
protected void GVRowBound(object sender, UI.GridViewRowEventArgs e)
{
msg += "GV Row Bound, ";
if (e.Row.RowType == UI.DataControlRowType.DataRow)
{
if ((e.Row.RowState & UI.DataControlRowState.Edit) != 0)
{
var item = (GreenPaperItem)e.Row.DataItem;
this.InvokeWaitTask(() =>
{
var txtbox = e.Row.FindControl("txtTime") as UI.TextBox;
if (txtbox != null)
{
txtbox.Text = $"{item.Date.Hour}:{item.Date.Minute}";
this.StateHasChanged();
}
return Task.CompletedTask;
});
//AddingTime = null;
}
}
}
But you should be able to use context directly in EditItemTemplate.
<EditItemTemplate TItem="GreenPaperItem">
<asp.TextBox ID="txtTime" TextMode="UI.TextBoxMode.Time"
CssClass="form-control" Text="@($"{context.Date.Hour}:{context.Date.Minute}")"
OnTextChanged="((s, e) =>
{
var timeText = ((UI.TextBox)s).Text;
var arr = timeText.Split(':');
var h = Convert.ToInt32(arr[0]);
var m = Convert.ToInt32(arr[1]);
AddingTime = new DateTime(2000, 1, 1, h, m, 0);
StateHasChanged();
})">
</asp.TextBox>
</EditItemTemplate>
With this way:
protected void GVRowBound(object sender, UI.GridViewRowEventArgs e)
{
msg += "GV Row Bound, ";
if (e.Row.RowType == UI.DataControlRowType.DataRow)
{
if ((e.Row.RowState & UI.DataControlRowState.Edit) != 0)
{
var item = (GreenPaperItem)e.Row.DataItem;
this.InvokeWaitTask(() =>
{
var txtbox = e.Row.FindControl("txtTime") as UI.TextBox;
if (txtbox != null) // is null
{
txtbox.Text = $"{item.Date.Hour}:{item.Date.Minute}";
this.StateHasChanged();
}
return Task.CompletedTask;
});
//AddingTime = null;
}
}
}
the txtbox is still null
Blazor server seems to be slower to complete addition, then there's no way.
Fortunately there was a simple way, I found the solution to be:
protected void GVRowBound(object sender, UI.GridViewRowEventArgs e)
{
msg += "GV Row Bound, ";
if (e.Row.RowType == UI.DataControlRowType.DataRow)
{
if ((e.Row.RowState & UI.DataControlRowState.Edit)
== UI.DataControlRowState.Edit)
{
var item = (GreenPaperItem)e.Row.DataItem;
InvokeAsync(() => this.StateHasChanged());
var txtbox = e.Row.FindControl("txtTime") as UI.TextBox;
if (txtbox != null) // is null
{
var zero = item.Date.Hour < 10 ? "0" : "";
txtbox.Text = $"{zero}{item.Date.Hour}:{zero}{item.Date.Minute}";
}
}
}
}
Awesome!
I have this gridview:
and I removed all non asp.net components from this grid, I expected to get a reference to the
txtTime
control inside gridview but it is null. is this possible?