How to go to Edit Mode in FormView? - c#

I have FormView:
<asp:FormView ID="fvReport" runat="server" DefaultMode="ReadOnly" AllowPaging="false" OnModeChanging="fvReport_ModeChanging" DataKeyNames="id">
protected void fvReport_ModeChanging(Object sender, FormViewModeEventArgs e)
{
switch (e.NewMode)
{
case FormViewMode.Edit:
fvReport.AllowPaging = false;
break;
}
}
in ItemTamplate I put LinkButton:
<asp:LinkButton ID="lbEdit" runat="server" CausesValidation="true" CommandName="Edit" CommandArgument='<%# Eval("id") %>'>Редактировать</asp:LinkButton>
Of course, FormView has EditItemTemplate section.
When I click Button, FormView is refreshed and stays in ReadOnly. What am I doing wrong?

you have to call ChangeMode method of FormView and pass the mode
fvReport.ChangeMode(DetailsViewMode.Edit);

Another option which I commonly use to go into edit mode from a formView is to add and define the EditItemTemplate element. This makes it a lot easier to make your application editable.
Within your formView you may need to change your DefaultMode to Edit. Also in your code behind try:
protected void fvReport_ModeChanging(Object sender, FormViewModeEventArgs e)
{
}
protected void lbEdit_Click(object sender, EventArgs e)
{
LinkButton lbEdit = (LinkButton)fvReport.FindControl("lbEdit");
if (sender == lbEdit)
{
fvReport.DataBind();
fvReport.ChangeMode(FormViewMode.Edit);
}
}

There could be other reasons why your FormView isn't switching over. It's usually down to badly formatted HTML. Your designer sometimes tells you of malformed sections by displaying something like this...
On those occasions when you don't get this obvious message, FormView not switching over is usually down to something a little less obvious, such as bad AssociatedControlId attributes. I would recommend looking at you labels, validators and anything where a control has to be associated to another. Something as small as this...
<asp:Label runat="server"
ID="labelAccessGrantedBy"
Text="Access Granted By"
AssociatedControlID="textAccessGranted" />
<asp:TextBox runat="server"
ID="textAccessGrantedBy"
CssClass="wmioSmall wFull"
Text='<%# Bind("access_granted_by") %>' />
Notice the deliberate use of textAccessGranted above, rather than the actual textAccessGrantedBy TextBox? That's where the command handling has failed for me in the past.

Related

Full postback on select & remove within update panel

I'm having issues with the asp.net textbox within an update panel. It works perfectly fine when adding or removing each individual character but if I highlight all of the text within the textbox, and then remove it a full postback occurs, not a partial postback which is expected.
Why is this happening? I haven't found anything related to this particular problem so it's likely I'm doing something wrong.
Example aspx:
<asp:UpdatePanel ID="updExample" runat="server" UpdateMode="Conditional" ChildrenAsTriggers="true">
<ContentTemplate>
<asp:Repeater ID="rptExample" runat="server" .... >
<ItemTemplate>
<asp:TextBox ID="txtExample" runat="server" ClientIDMode="static" Text='<%# Eval("Example") %>' OnTextChanged="txtExample_TextChanged" AutoPostBack="true"></asp:TextBox>
</ItemTemplate>
</asp:Repeater>
</ContentTemplate>
</asp:UpdatePanel>
Example TextChanged Event:
protected void txtExample_TextChanged(object sender, EventArgs e)
{
updExample.Update();
}
Additional Notes:
Switching UpdateMode to 'Always' doesn't work.
Karthikeyan Nagaraj pointed out in the comments to try adding triggers alongside what I already had. I did in fact already have this, however, I was assigning the trigger in the ItemDataBound event which I realized was incorrect after reinvestigating. The ItemCreated event was much more suited.
I had no issues finding the control in the ItemCreated event, however adding a new async postback trigger to the update panel gave me grief and said the control couldn't be found when changing the text. To resolve this, I used the script managers RegisterAsyncPostBackControl(); method as shown below.
protected void rptExample_ItemCreated(object sender, RepeaterItemEventArgs e)
{
var input = e.item.FindControl("txtExample");
if (input != null) {
ScriptManager sm = ScriptManager.GetCurrent(this);
sm.RegisterAsyncPostBackControl(input);
}
}

Change asp:Label text from C# code behind

I've been trying with this for an hour or so; just can't seem to figure out.
I have an asp:Button on an aspx page, required to complete a couple of functions, one of which is to change the text of an asp:Label. This seems like it should be simple and other online posts indicate that I'm approaching the problem correctly but...
The problem is simple but it's killing me. In an effort to debug/troubleshoot, I've stripped the code right back to very basics:
protected void Page_Load(object sender, EventArgs e)
{
allValidationMsg.Text = "Original text";
}
protected void btnRegister_Click(object sender, EventArgs e)
{
allValidationMsg.Text = "Text changed";
}
When the button is clicked, nothing happens. I'm sure it's something simple that I'm missing.
Update:
<asp:Label id="allValidationMsg" runat="server" height="22px" ForeColor="Red"></asp:Label>
<asp:Button class="navbutton" ID="btnRegister" runat="server"
Text="Register User" OnClick="btnRegister_Click" />
I think when you click on the Button, Page_Load is called again and the original text remains. Try this
protected void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
allValidationMsg.Text = "Original text";
}
Apart from this, I assume you register the event handler for the button in the Markup as I cannot see it anywhere in your code-behind
<asp:Button id="Button1" runat="server" OnClick="btnRegister_Click" />
Possibly you have forgotten to bind button click to the handler.
You could do it something like that in code-behind:
mybutton.Click+=btnRegister_Click;
Or in aspx:
<asp:Button id="Button1"
Text="Click here for greeting..."
OnClick="btnRegister_Click"
runat="server"/>
Solved; the problem appears to have been with the use of a CompareValidator. Don't really understand why but when this validator is commented out, problem solved. Funnily enough, RequiredField and RegularExpression validators on same page cause no issues..
Hey I think I know what it is. In your markup does your label look like this??
<asp:Label ID="Label1" runat="server" >Some text</asp:Label>
You want this in your markup:
<asp:Label ID="Lable1" runat="server" text ="some text"></asp:Label>
I have had this happen before. If you change the markup to that. It should work.
I can see that you wrote "onclick" instead of "OnClick" in the markup (case). Possibly it is the cause of the issue.
UPDATE1
Could you try to do so (check if postback works):
protected void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
{
allValidationMsg.Text = "Original text";
}
else
{
allValidationMsg.Text = "After postback";
}
}
If the text is changing after pressing the button?
UPDATE2 Also, please try to make some changes in the text to understand if a new version really deploys (to exclude strong caching issues).
UPDATE3 You can try to do binding in codebehind (and delete it from aspx).

Databind fires after ItemUpdated event

I'm using an asp.net 4 web site project (C#) in VS2008 and I have a FormView with ItemUpdated event:
<asp:FormView ID="FormView1" runat="server" DataSourceID="ds1" OnItemUpdated="FormView1_ItemUpdated">
<EditItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("col1") %>' />
</EditItemTemplate>
</asp:FormView>
protected void FormView1_ItemUpdated(object sender, EventArgs e)
{
FormView1.DataBind(); // adding this line even doesn't help
TextBox box = FormView1.FindControl("TextBox1") as TextBox;
box.Enabled = false;
}
But I can't figure out, why an extra "FormView1.DataBind()" or Render(?) happens AFTER the ItemUpdated event. The result is that my code in the ItemUpdated event gets like "overwritten" and the TextBox1 doesn't get disabled.
When I set a breakpoint to the last line "box.Enabled = false;" then I see that after the ItemUpdated event it jumps to the aspx page again and steps through the TextBoxes.
Disabling this TextBox1 from another GridView1_SelectedIndexChanged works fine.
Is there any way to see the "current lifecycle progress" in debugging?
EDIT:
To clarify the reasoning...
I have a GridView1 where selecting the item populates the abovementioned FormView1. The point is that I need to disable some of the TextBoxes in the FormView1 based on, for example, user access levels.
Selecting the item from GridView1 disables the TextBox1 just fine, but when I click the Update button on the FormView1 then all TextBoxes are enabled, even if I see in the debugger code running through the GridView1_SelectedIndexChanged() function. And after I re-select the gridview item, the correct TextBoxes are disabled again.
Using even this code:
<asp:FormView ID="FormView1" runat="server" DataSourceID="ds1" DefaultMode="Edit" OnItemUpdated="FormView1_ItemUpdated">
<EditItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("col1") %>' />
<asp:TextBox ID="TextBox2" runat="server" Text='<%# Bind("col2") %>' />
<asp:Button ID="Btn1" runat="server" CommandName="Update" Text="Update" />
</EditItemTemplate>
</asp:FormView>
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
if (UserAccess() == false) {
TextBox box2 = FormView1.FindControl("TextBox2") as TextBox;
box2.Enabled = false;
}
}
protected void FormView1_ItemUpdated(object sender, EventArgs e)
{
GridView1_SelectedIndexChanged(sender, e);
}
Maybe I should disable my Textboxes via another event?
This doesn't make sense, please explain more about why you are trying to disable the TextBox, have you just left the ItemTemplate off in your question? or is it actually missing? if it's missing why?
The TextBox is in the FormView's EditItemTemplate, so will only be visible when the FormView is in edit mode. After clicking update or cancel the TextBox will no longer be rendered, and the ItemTemplate is rendered instead. So there should be no need to set the TextBox to be disabled.
EDIT
Ok since you edited your question. You need to use the OnDataBound event of the FormView, which occurs at the end of binding, and disable your TextBoxes at that point.
aspx
<asp:FormView ID="FormView1" runat="server" DataSourceID="ds1"
OnDataBound="FormView1_DataBound">
<EditItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("col1") %>' />
</EditItemTemplate>
</asp:FormView>
aspx.cs
protected void FormView1_DataBound(object sender, EventARgs e)
{
if (UserAccess() == false) {
TextBox box2 = FormView1.FindControl("TextBox2") as TextBox;
box2.Enabled = false;
}
}
Rather then using gridview selected Index change you can use DataBound event on formview, so your logic would fire everytime the formview is rebind.

Calling a function in code behind by using an imagebutton in a gridview [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Calling a functon in code behind by using an imagebutton in a gridview
I have an ImageButton within a gridview in .aspx on clicking this imagebutton i have to call a function.
This is how i tried and the function was not being called.
Code inside.aspx page:
<GridView ......>
<asp:HyperLink ID="HyperLink2" runat="server" NavigateUrl='<%# DataBinder.Eval(Container.DataItem,"VehID","mngVeh.aspx?delid={0}") %>'>
<asp:ImageButton runat="server" ID="DeleteUrlImageButton" ImageUrl="~/images/delete.jpeg" width='24' height='24'
OnClick="DeleteUrlImageButton_Click"
OnClientClick="return confirm('Are you sure you want to delete?');" />
</asp:HyperLink>
</GridView>
code in .aspx.cs page:
public void DeleteUrlImageButton_Click(object sender, EventArgs e)
{
//code to perform the necessary action.
}
I think you're mixing controls up here.
I would use an ImageUrl on the asp:hyperlink itself, and also the OnClick property. You can handle the OnClientClick by using javascript inside the NavigateUrl property.
I don't see a reason for having a nested ImageButton - I doubt this even works.
Or, just remove the asp:hyperlink completely and do a redirect inside the OnClick event.
The problem here is twofold: First, the click event does not bubble up through the GridView, which is why the event is not firing. Second, that there will be an ImageButton for each row of the GridView, and you need to identify which row the event originated from (or more accurately, which underlying datasource record that row corresponds to).
A common way to approach this problem is to use the ImageButton.CommandName and ImageButton.CommandArgument properties, and handle the GridView.RowCommand event.
Markup:
<asp:GridView ID="GridView1" runat="server" OnRowCommand="GridView1_RowCommand">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:ImageButton runat="server" ID="DeleteUrlImageButton" ImageUrl="~/images/delete.jpeg"
Width='24' Height='24' OnClientClick="return confirm('Are you sure you want to delete?');"
CommandName="MyDelete" CommandArgument='<%# Eval("RecordId") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Code:
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if ((e.CommandName == "MyDelete") && (e.CommandArgument != null))
{
//Add delete code here using e.CommandArgument to identify the correct record.
// For instance:
MyDataObject obj = new MyDataObject();
obj.RecordId = int.Parse(e.CommandArgument.ToString());
MyDataObject.Delete(obj);
}
}
Edit: I see you provided the name of the ID field in your example, so you would probably want to replace "RecordId" in my example with "VehID".

DetailsView FindControl() returns null after some postbacks

I've been working for a long time with GridViews and DetailsViews, but yesterday I've come across a new scenario, which I quite do not understand.
I have a GridView with ImageButton (CommandName="Insert") which will change the mode of the DetailsView to Insert. Afterwards I'll look for a DropDownList inside that DetailsView and add some items dynamically. Works fine, but one first the first time I press that ImageButton. If I click on "Cancel" in the DetailsView and press the ImageButton again, the .FindControl() Method returns null. What life cycle problem am I facing here?
I've created this sample: (To make it run in your Visual Studio, just bind a DataSource to the DetailsView, otherwise it will not be rendered)
Markup:
<asp:GridView ID="gvCategory" runat="server" OnRowCommand="gvCategory_RowCommand">
<Columns>
</Columns>
<EmptyDataTemplate>
<asp:ImageButton ImageUrl="~/images/add.png" ID="ibAdd" runat="server" CommandName="Insert" />
</EmptyDataTemplate>
</asp:GridView>
<asp:DetailsView ID="dvCategory" runat="server" Width="150px" AutoGenerateRows="false"
AutoGenerateInsertButton="True" DataSourceID="LinqDataSource1">
<Fields>
<asp:TemplateField HeaderText="foo">
<InsertItemTemplate>
<asp:DropDownList ID="ddlCategory" runat="server" Width="150"></asp:DropDownList>
</InsertItemTemplate>
</asp:TemplateField>
</Fields>
</asp:DetailsView><asp:LinqDataSource ID="LinqDataSource1" runat="server"
ContextTypeName="WebApplication1.DataClasses1DataContext"
TableName="Categories"></asp:LinqDataSource>
Codebehind:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
this.gvCategory.DataBind();
}
}
protected void gvCategory_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Insert")
{
this.dvCategory.ChangeMode(DetailsViewMode.Insert);
DropDownList _ddlCat = (DropDownList)this.dvCategory.FindControl("ddlCategory");
if (_ddlCat != null)
{
_ddlCat.Items.Clear();
_ddlCat.Items.Add(new ListItem() { Text = "-- empty --", Value = "-1" });
}
}
}
I have also tried using a ItemTemplate, and not a InsertItemTemplate, but this results in the same. After using the ChangeMode-Method the DetailsView.CurrentMode == InsertMode. The only thing I can think of is, that the markup is already generated for the ItemTemplate and changing the Mode to InsertMode can't affect the rendered markup, or something like this.
Does anybody have a solution to this? =)
I think you are on the right track. It's hard to tell without seeing all of the code, but basically any time you change the rendering mode of a row in a repeater-type control you need to rebind it so that it's re-rendered. The fact that FindControl is returning NULL means only one thing: THE CONTROL IS NOT THERE. Which means it was not rendered. You can verify this by looking at the control hierarchy.
So, in your handler for Cancel are you rebinding?

Categories