I feel a little embarassed posting two questions relating to the same problem, but the first one ended up answering a question that I believe is unrelated to the solution so I'm leaving it up and outlining what I'm trying to accomplish with the hopes that someone can help out a .Net noob.
What I need to be able to do is create a field in my gridview that contains a link that passes two variables. One is pulled from within the gridviews datasource and the other needs to be pulled from a textbox control outside the gridview.
From what I've read so far you cannot use a hyperlinkfield for this as the datanavigateurlfields cannot be set to pull from anything but the gridview's data source.
What I attempted to do was create a template field where in the itemtemplate I called:
Test
That comes back with an error like this:
DataBinding: 'System.Data.DataRowView' does not contain a property with the value 'TestData'
Any clues to make this happen would be appreciated, like I said I'm pretty new to .Net so please be gentle. I tried to do my homework before posting this.
How about putting a hyperlink server control in your GridView template column as below.
<asp:Hyperlink id="hyperlink" runat="server" onDataBinding="hyperlink_DataBinding" text="Click ME" />
Then in your code behind add this data binding event for the hyperlink.
protected void hyperlink_DataBinding(object sender, EventArgs e) {
HyperLink link = (HyperLink) sender;
string param1 = Eval("field").ToString();
string param2 = ExampleList.SelectedItem.Value;
link.NavigateUrl = "example.aspx?e=" + param1 + "&f=" + param2;
}
Related
I really hope that someone can help, pointing me in the right direction. I'm still new to the more advanced features of asp.net / C#.
What i need is a div, in that div i would want some informations from the database. furthermore i want a textbox with a number and an arrow up and down to increase/decrease the amount in the textbox. And at last a button outside the div to submit the value.
Now the tricky part (for me), is that one div is not enough, I need one div for each "person" in the database. i can easily make that, but.. if i add it dynamically from the .aspx.cs file i am not able to access the value like : textbox1.text; because textbox1 does not exist in the code before it is created.
I have looked at listview and a repeater, but those seems more like they're for making lists, and i need more than that, as i need some functionally too.
The way i would do it now is to add the div by innerhtml. and then adjust the amount by a for loop which also inserts the information from the database which i got in an array. But as said, that doesn't really do the trick when i need to access the textbox and stuff.
Thanks in advance for just looking at it.
EDIT:
I'm not looking for at complete solution, i just want some directions.
I will asume by your post description that by asp.net you mean webForms. If you're new on asp.net development, you have to know that there are different development, in the past (but still very commonly used) you would use WebForms, now at days the trends are using asp.net MVC framework.
now back to your question:
in asp.net WebForms, you have your code defined in two sides: your markup (HTML code normally in a .aspx file) and your code-behind (c# or vb code normally in a .aspx.cs or .aspx.vb).
what I would suggest you to do, is to add your logic for retrieving data from your database in your page_load() function of your code-behind, with this data you would normally use a loop to read all your results and for each result you would create your div with your textbox inside (the trick is using native .net framework classes instead of inserting the HTML directly). a simple example:
protected void Page_Load(object sender, EventArgs e)
{
string[] personsIDs; //<-- this came from your database
Dictionary<string, TextBox> textBoxes = new Dictionary<string, TextBox>();
foreach(string personID in personsIDs)
{
TextBox personTextBox = new TextBox();
personTextBox.ID = "textBox"+personID;
textBoxes.add("textbox"+personID, personTextBox);
}
I explain you:
first, I'm assuming there is an array of the personsIDs, so I created a dictionary (key -> value object) using strings as keys and TextBoxes as values.
then using a foreach I read all the personsID's, and for each one of them I create a new TextBox UIControl and add it to the dictionary using the personID as key. I also added its ID property as "textbox"+PersonID.
this way you can access your textboxes from code-behind by using your dictionary:
textBoxes["textbox"+personID] //(e.g: textBoxes['textBox11'])
but also, since your textBox.ID is equal to textbox+personID, you can also reference it after page has been rendered (e.g. using javascript).
now to add this controlers to your page, just use a container(UIControl) that already exists on your page, and use
container.controls.add(textbox);
this process can be expanded for extra elements, for instance:
1.- have a main placeholder already defined in your page:
<asp:Panel ID= "Panel1" runat = "server">
2.- in your code-behind for each person create a new panel and add all the elements you want inside that panel:
//this goes inside your foreach
Panel innerPanel = new Panel();
TextBox textBox = new TextBox();
Label label = new Label();
innerPanel.controls.add(textbox);
innerPanel.controls.add(label);
////
finally add your innerPanels in to your main panel:
panel1.controls.add(innerPanel);
so there you go, that's basically the idea, hope this helps.
I have a repeater in one of the sublayouts in Sitecore 6.6. rev 120918. Inside this repeater, I have a placeholder. On ItemDataBound, I assign a key with a GUID to it, and using Nick Wesselman's GetAllowedRendering pipeline, I am able to render the insert options for this.
The repeater code is very simple:
<asp:Repeater runat="server" ID="rptrTimelineItemsEdit" OnItemDataBound="rptrTimelineItemsEdit_OnItemDataBound">
<ItemTemplate>
<sc:Placeholder ID="scTimelineItemPlaceholder" Key="timelineitemcontent" runat="server" />
</ItemTemplate>
</asp:Repeater>
The Item Data bound is also pretty simple:
protected void rptrTimelineItemsEdit_OnItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
Item item = (Item)e.Item.DataItem;
Placeholder scTimelineItemPlaceholder = (Placeholder)e.Item.FindControl("scTimelineItemPlaceholder");
scTimelineItemPlaceholder.Key = "timelineitemcontent" + item.ID.ToString().ToLower();
}
}
Everything works up to this point. After I choose the sublayout I want to insert in the placeholder, it throws me an in the JS error popup. After inspecting in the chrome inspector, I see the error is:
Could not find the rendering in the HTML loaded from server PlaceholderChromeType.js:601
Sitecore.PageModes.ChromeTypes.Placeholder.Sitecore.PageModes.ChromeTypes.ChromeType.extend._frameLoaded
So - it would seem like that in the page reload, the sublayout renderings are happening before the repeater bindings, so it can't find the placeholder key.
I did some google, and found that there is a way to change the layout engine sequence using the layoutpageevent setting:
However, this didn't solve my problem. I'm out of ideas. Help!
Hi there Ive found a solution to this issue, it had me stumped as well.
It only occurs to placeholders that sit under a repeater.
Overwrite PlaceholderChromeType.js in Website\sitecore\shell\Applications\Page Modes\ChromeTypes\
With the one ive dropboxed (also available on the credit link below)
https://www.dropbox.com/s/7m99b8jgdz3cgl2/PlaceholderChromeType.
Your keys then have to have dynamic in them for it to work.
Example code:
protected void R1_ItemDataBound(Object Sender, RepeaterItemEventArgs e)
{
var p = e.Item.FindControl("andysplaceholder") as Placeholder;
p.ID = "Andy" + (e.Item.ItemIndex + 1);
p.Key = "dynamic" + p.ID;
}
<asp:repeater id="MyRepeater" runat="server" OnItemDataBound="R1_ItemDataBound">
<ItemTemplate>
<sc:placeholder runat="server" id="andysplaceholder" key="dynamicandysplaceholder" ></sc:placeholder>
</ItemTemplate>
</asp:repeater>
On top of this i do my repeater binding in the oninit method
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
and i set the web.config setting from preInit to load
<setting name="LayoutPageEvent" value="load" />
Although that might be overkill, I will revert today to page_load and preinit today and see if it still works.
Credit to Sitecore support and Mickey Rahman for this http://mickeyrahman.wordpress.com/2014/05/05/an-ode-to-sitecore-support/#respond
This should also work with the dynamic key apprach from Nick, you'll just have to make sure the keys generated by his code have dynamic in them
You have not implemented it in the way it's explained by Nick.
What you need to do is create a WebControl class for your Dynamic Placeholder.
That will ensure that things are processed in the same order as it would have with a 'real' Placeholder.
So the first thing I would do is make sure you do it in the same way as it's been described by Nick.
Then verify that it works with just 1 dynamic placeholder on the page.
Secondly, you should take a look at this blog post: Dynamic Placeholders and IExpandable
It explains how to deal with adding multiple dynamic placeholders in repeaters (and other controls).
He also thought that it had something to do with the change in the LayoutPageEvent, but it did not turn out to be that.
EDIT:
I've reproduced the issue and I highly doubt that you're going to solve it with this approach.
The placeholders are not loaded yet when the Page Editor is requesting their renderings after trying to add controls to them.
Even when you create the Placeholders in the OnInit (which is the earliest), it doesn't work.
If I get more time I'll try to look into it further.
Ruud referenced my blog post Dynamic Placeholders and IExpandable in his answer, and I think that he's definitely on the right track. I know that you haven't used dynamic placeholders in the way that I describe, however you are still creating placeholders dynamically.
I personally have never had any success with the LayoutPageEvent; which is why I decided to post about the use of IExpandable as it isn't something that's been highlighted that much.
You ought to create your placeholders in the Expand method and also expand them after you add them to the page. I would personally advise against using a Repeater to do so - add them to the controls collection or maybe to a normal ASP.Net PlaceHolder control.
public class YourSublayout : UserControl, IExpandable
{
public void Expand()
{
var myListOfItems = GetItems()
foreach (var item in myListOfItems)
{
var placeholder = new Placeholder { Key = "key" + item.ID.ToString() };
container.Controls.Add(placeholder); // add to a control container
placeholder.Expand();
}
}
}
Hopefully that should get you a bit further (if you haven't solved it already). Just keep in mind the other things I mention on my post, namely that the Expand method can be called before the control gets added to the page, and so getting your DataSource may break if you rely on getting it from the parent control.
I am working on an Asp.net, C# Application.
I want to Refresh the webpage after I clicking on “Update” LinkButton; in Grid view. I have tried the following code; however it just refreshes the page without saving the updated data in Grid view.
protected void LinkButton1_Click1(object sender, EventArgs e)
{
Response.Redirect(Request.RawUrl.ToString());
}
Name of DataSource SqlDataSourcePlan
SELECT [PlanID], [Deposit], [DepositReturn], [Discount] FROM [PaymentPlan] WHERE ([Ref] = #Ref)
UPDATE [PaymentPlan] SET [Deposit] = #Deposit, [DepositReturn] = #DepositReturn, [Discount] = #Discount WHERE [PlanID] = #original_PlanID
Use RawUrl instead:
Response.Redirect(Request.RawUrl)
The raw URL is defined as the part of the URL following the domain
information. In the URL string
http://www.contoso.com/articles/recent.aspx, the raw URL is
/articles/recent.aspx. The raw URL includes the query string, if
present.
Edit: "without saving the updated data in Grid view"
Why do you think that redirecting the page to itself should save something somewhere?
Have a look at this tutorial: Inserting, Updating, and Deleting Data with the SqlDataSource (C#)
I assume that you actually want to update the GridView instead of the whole page. Then you should call GridView.DataBind().
My guess (without some other informations in the code it is difficult to say) is that althought the information is saved in the database, the datasource for the gridview is not refreshed with the new values.
I have seen this problem often regarding this part.
You have to rebind the gridview with Page.DataBind or GridViewName.DataBind() (where GridViewName is the name of your gridview) before the redirect.
You probably don't reload the GridView at PageLoad or PageLoad does not occure (can't know without the server code). If that would work properly, you would not need the databinding before redirecting.
I have this type of code in aspx but wish to generate it in code behind. What would be the equivalent?
<uc1:editformcontrol ID="EditFormControl1" runat="server" CategoryID=' <%#Bind("CategoryID") %>' />
The question pertains mainly to the binding
It's difficult to say without knowing your data model. What kind of data source are you using? You could try adding this line to the Page_Load method:
int categoryId;
categoryId = WHEREEVER YOU'RE STORING THIS VALUE...
EditFormControl1.CategoryID = categoryId;
Usually, you override the OnDataBound event on your control and bind the data there.
See here one example.
Can anyone give me some pointers on how to display the results of an XPath query in a textbox using code (C#)? My datascource seems to (re)bind correctly once the XPath query has been applied, but I cannot find how to get at the resulting data.
Any help would be greatly appreciated.
XMLDataSource is designed to be used with data-bound controls. ASP.NET's TextBox is not a data-bound control. So to accomplish what you want you either have to find a textbox control with data binding or display the result in some other way.
For example, you could use a Repeater control and create your own rendering template for it.
<asp:Repeater id="Repeater1" runat="server" datasource="XMLds">
<ItemTemplate>
<input type="text" value="<%# XPath("<path to display field>")%>" />
</ItemTemplate>
</asp:Repeater>
Some more information would be nice to have to be able to give you a decent answer. Do you have any existing code snippets you could publish here?
The general idea is to use the XmlDataSource.XPath property as a filter on the XmlDataSource.Data property. Did you try displaying the contents of the Data prop in your textbox?
Based on a slection in a DropDownList, when the SelectedIndexChanged event fires, the XPath for an XMLDataSource object is updated:
protected void ddl_SelectedIndexChanged(object sender, EventArgs e)
{
XMLds.XPath = "/controls/control[#id='AuthorityType']/item[#text='" + ddl.SelectedValue + "']/linkedValue";
XMLds.DataBind();
}
The XPath string is fine, I can output and test that it is working correctly and resolving to the correct nodes. What I am having problems with, is getting at the data that is supposedly stored in the XmlDataSource; specifically, getting the data and outputting it in a TextBox. I'd like to be able to do this as part of the function above, i.e.
protected void ddl_SelectedIndexChanged(object sender, EventArgs e)
{
XMLds.XPath = "/controls/control[#id='AuthorityType']/item[#text='" + ddl.SelectedValue + "']/linkedValue";
XMLds.DataBind();
myTextBox.Text = <FieldFromXMLDataSource>;
}
Thank you for your time.