in a datatable you can rename column as follows:
dt.Column[0].ColumnName="name";
Is it possible to do something similar with list<MyType>? I need to retrun list of objects with modified column names. to bind to a gridview some special way.
You can go with anonymous types:
var yourList = new List<MyType>{ ... };
var newList = yourList.Select( i=> new { NewColumn = i.OldName });
In the asp.net gridviews you can use Bound Fields to Bind Properties and Set the Column Headers to whatever you want
<asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="False" >
<Columns>
<asp:BoundField DataField="MyProperty" HeaderText="My Custom Column Heaer" />
</Columns>
</asp:GridView>
Just make sure the MyProperty exists on the MyType and you should be good.
Related
I'm having problems retrieving the current row by changing the status of a DropDownList in the row. My code for the GridView is:
<asp:GridView ID="grdMappingList" runat="server" OnPageIndexChanging="grdMappingList_PageIndexChanging" AutoGenerateColumns="false" AllowPaging="true" PageSize="10" ShowHeaderWhenEmpty="true" UseAccessibleHeader="true" CssClass="table table-hover table-striped segment_list_tbl" >
<PagerStyle CssClass="grid_pagination" HorizontalAlign="Right" VerticalAlign="Middle" BackColor="#DFDFDF" />
<Columns>
<asp:BoundField HeaderText="Mapping Id" DataField="MAPPING_ID"></asp:BoundField>
<asp:BoundField HeaderText="PDM Name" DataField="PDM_NAME"></asp:BoundField>
<asp:BoundField HeaderText="PDM EntityID" DataField="PDM_ENTITY_ID" Visible="false"></asp:BoundField>
<asp:TemplateField HeaderText="Mapping Status" HeaderStyle-CssClass="width_120 aligned_center" ItemStyle-CssClass="width_120 aligned_center" Visible="true">
<ItemTemplate>
<asp:DropDownList id="ddlMappingStatus" runat="server" SelectedValue='<%# Bind("MappingCompleted") %>' OnSelectedIndexChanged="ddlMappingStatus_SelectedIndexChanged" AutoPostBack="true">
<asp:ListItem Text="Done" Value="DONE"></asp:ListItem>
<asp:ListItem Text="Not Done" Value="NOT DONE"></asp:ListItem>
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
And the code behind is:
protected void ddlMappingStatus_SelectedIndexChanged(object sender, EventArgs e)
{
int MappingID = Convert.ToInt16(grdMappingList.SelectedRow.Cells[0].Text);
DropDownList ddgvOpp = (DropDownList)grdMappingList.SelectedRow.FindControl("ddlMappingStatus");
if (ddgvOpp.Equals("DONE"))
{
}
}
I am getting an error on this line:
DropDownList ddgvOpp (DropDownList)grdMappingList.SelectedRow.FindControl("ddlMappingStatus");
and this line:
int MappingID = Convert.ToInt16(grdMappingList.SelectedRow.Cells[0].Text);
It seems that I can't retrieve the values! I dont know why. When I choose a new status from the DropDownList, I want to get all the values of the row in order to update the record.
Unfortunately, SelectedRow does not mean what you think it means. It doesn't just simply mean the current row you are working on or the current row with the controls that you are using. That property must get set somehow. This is usually done through a "Select" button on the GridView, such as an <asp:ButtonField> with the command name "Select".
You really do not need this however. You just need the row you are working with. Since you are using the SelectedIndexChanged event of your DropDownList, you already have what you need. You just need to go about it a different way.
First, get the DropDownList. Then get the row of the DropDownList. Now do whatever you need with the row.
But, from your code, it looks like you may not even need the row. You just need the value of the DropDownList. So you could skip that all together. But if you do need the row, here is how you would do that too.
protected void ddlMappingStatus_SelectedIndexChanged(object sender, EventArgs e)
{
DropDownList ddlMappingStatus = (DropDownList)sender;
if(ddlMappingStatus.SelectedItem.Text.ToUpper() == "DONE")
{
}
GridViewRow row = (GridViewRow)ddlMappingStatus.NamingContainer;
}
Now when you use <asp:BoundField> controls in your GridView, getting their values isn't very clean. You are forced to hardcode the column index like you were doing:
GridViewRow row = (GridViewRow)ddlMappingStatus.NamingContainer;
String mappingID = row.Cells[0].Text;
I tend to prefer using <asp:TemplateField> controls so I can use FindControl() to get what I am after. This prevents any reordering of the columns from breaking the code, as you'd have to hardcode different indexes. So for example, to find that DropDownList (since it already is a <asp:TemplateField>), you'd do something like this:
DropDownList ddlMappingStatus = (DropDownList)row.FindControl("ddlMappingStatus");
i want to display some fields from my database in GridView but my problem is, it show all the field i want in one new field
this is my code
<asp:GridView ID="GridView1" runat="server">
</asp:GridView>
and this is c# code
GridView1.DataSource = (from x in db.Products
select x.name + x.phoneNumber + x.proviance + x.description + x.city + x.Address).ToList();
GridView1.DataBind();
how to display some fields of a table (not all fields) into gridView in c# in asp.net
With Respect
So by default GridView generates columns for all fields/columns in the data set it was given. To select what you see you need to turn this off and explicitly declare desired columns:
<asp:GridView ID="GridView1" runat="server"
AutoGenerateColumns="false">
<Columns>
<asp:BoundField DataField="name of the column in the data set"
HeaderField="header to show on the UI"/>
... and so on for other columns ...
</Columns>
</asp:GridView>
I am trying to check a CheckBox for certain rows in a GridView if there are records in the database. Lets say I have product 1,2,3,4 in a category and the products available for packaging are 1 and 3. Inside my GridView, for each category, I only checked the checkbox of product 1 and 3 instead of all the products in that category. Here is how I set up my GridView:
<!-- Collapsible panel extender body -->
<asp:Panel ID="pBody1" runat="server" CssClass="cpBody">
<asp:Label ID="lblBodyText1" runat="server" />
<!-- Grid view to show products based on each category -->
<asp:GridView ID="gvProduct" runat="server" AutoGenerateColumns="False" Width="998px" CellPadding="4" ForeColor="#333333" GridLines="None" ShowHeader="False" DataKeyNames="id">
<AlternatingRowStyle BackColor="White" ForeColor="#284775" />
<Columns>
<asp:TemplateField HeaderText="Select" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:CheckBox ID="cbSelect" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="name" HeaderText="Name" ItemStyle-Width="750px" />
<asp:BoundField DataField="categoryName" HeaderText="Category" />
<asp:BoundField DataField="inventoryQuantity" HeaderText="Quantity" />
</Columns>
</asp:GridView>
</asp:Panel>
And from the code behind, first I get all the products based on category. I named it as prodList. Then, I get all the products available for packaging. I named it as distSPUItemList. I loop thru both lists and if their name match, I get the row and check the checkbox:
List<ProductPacking> prodList = new List<ProductPacking>();
//Get all products based on category
prodList = prodPackBLL.getAllProductByCategory(category);
gv.DataSource = prodList;
gv.DataBind();
List<DistributionStandardPackingUnitItems> distSPUItemList = new List<DistributionStandardPackingUnitItems>();
distSPUItemList = packBLL.getAllSPUItemByDistributionID(distributionID);
for (int i = 0; i < distSPUItemList.Count; i++)
{
for (int j = 0; j < prodList.Count; j++)
{
GridView gvForCheckBox = (GridView)e.Item.FindControl("gvProduct") as GridView;
foreach (GridViewRow gr in gvForCheckBox.Rows)
{
if (prodList[j].name == distSPUItemList[i].name)
{
CheckBox cb = (CheckBox)gr.Cells[0].FindControl("cbSelect");
cb.Checked = true;
}
}
}
}
However, for the CheckBox, it just checks all the products inside that category instead of checking the one that match between prodList and distSPUItemList. Why is this?
I believe the best way to solve your problem is to determine if this CheckBox should be checked prior to Data Binding your "gvProduct" control. Setting this value in the Data Source ahead of time will prevent you from having to re-access the GridView later on.
If this is not an option, the solution below will work, but is more clunky since you have to re-access the GridView and then iterate its Row collection.
Disclaimer, done in my head without VS2012, so please forgive any minor syntax errors. I modified your code to remove parts that were not specifically relevant to this solution. First, get your two lists of objects:
List<ProductPacking> prodList = prodPackBLL.getAllProductByCategory(category);
List<DistributionStandardPackingUnitItems> distSPUItemList = packBLL.getAllSPUItemByDistributionID(distributionID);
Next, you can use a simple LINQ query to compare lists of objects finding ProductPacking objects whose name property are equal to the items in distSPUItemList. This creates a new collection of only objects that match:
var available = // Start with prodList
from a in prodList
// perform an inner-join between prodList and distSPUItemList only returning objects whose names match
// (x => x.name == a.name) compares b.name to a.name, this is specifically what enforces that names match.
from b in distSPUItemList.Where(x => x.name == a.name)
// after inner joining is done, only select objects from prodList (we could select more things, but we only need these.)
select a;
And lastly, you may iterate the gridview rows and see if the name property shown in the GridView was in the list of products available for packaging, if it was, mark the checkbox checked.
GridView gvForCheckBox = (GridView)e.Item.FindControl("gvProduct") as GridView;
foreach (GridViewRow gr in gvForCheckBox.Rows)
{
// query the available collection to see if it contains a ProductPacking object with a name equal to what is in the current GridView row.
// I would recommend to match on a PK
// disclaimer, matching on name may be a problem if two different products can have the same name.
if (available.Where(x=>x.Name==gr.Cells[1].Text).Any())
{
CheckBox cb = (CheckBox)gr.Cells[0].FindControl("cbSelect");
cb.Checked = true;
}
}
I want to create a table format with two columns where each row will have a ProductTitle and its corresponding URL.
I am using the following code which gives the info in table format. I displays entire anchor tag in second column.
But i want only the Text to be displayed as link in second column. On click of which it should open the URL page.
DataTable dt = new DataTable();
dt.Columns.Add("ProductTitle");
dt.Columns.Add("Link");
DataRow dr = dt.NewRow();
dr["ProductTitle"] = "GOOGLE";
dr["Link"] = "<" + "a href=\"" + "http://www.google.com" + "\">Google" + "</a>";
dt.Rows.Add(dr);
Gridview1.DataSource = dt;
Gridview1.DataBind();
Could anyone suggest.
You could modify the .aspx file as follows:
...
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false">
<Columns>
<asp:BoundField DataField="ProductTitle" HeaderText="Product Title" />
<asp:BoundField DataField="Link" HtmlEncode="false" HeaderText="Link" />
</Columns>
</asp:GridView>
...
So, you should disable the automatic column generation by setting AutoGenerateColumns="false" and format the Columns section of the GridView. Please note the key element here for the link rendering, which is the HtmlEncode="false" attribute. You can also set everything in the code behind file:
GridView1.AutoGenerateColumns = false;
var productTitleField=new BoundField();
productTitleField.DataField="ProductTitle";
productTitleField.HeaderText="Product Title";
var linkField=new BoundField();
linkField.DataField="Link";
linkField.HeaderText="Link";
linkField.HtmlEncode=false;
GridView1.Columns.Add(productTitleField);
GridView1.Columns.Add(linkField);
Try this
dr["Link"] = "<a href='http://www.google.com'>Google</a>";
I tried
Label1.Text = "<a href='http://www.google.com'>Google</a>";
It works.
Second try :
We cannot save any thing else other than .NET types like string,int .etc ,so try asp:HyperLink like this
<ItemTemplate>
<asp:HyperLink ID="HyperLink1" runat="server" Text='<%# Eval("ProductTitle")%>' NavigateUrl='<%# Eval("Link") %>'></asp:HyperLink>
</ItemTemplate>
and
dr["ProductTitle"] = "Goole";
dr["Link"] = "http://www.google.com";
There is actually a specific column designed just for what you want to do, it's the HyperLinkField column.
<asp:HyperLinkField
HeaderText="Header"
DataTextField="LinkText"
DataNavigateUrlFields="LinkURL"
DataNavigateUrlFormatString="http://google.com/q={0}" />
You can then ensure that your data source has the appropriate columns for the link text and navigate url fields.
You can configure it if you have a fixed text or fixed url to use the Text or NavigateURL properties instead of the Data... counterparts, and you can use or not use format strings as needed.
I'm trying to set the first column elements as hyperlinks redirecting to another page..but somehow it doesn't seem to work no matter what I try.
reportTable.Rows[i].Cells[1].Text = report.reportId.ToString();
TableCell tCell = new TableCell();
tCell.Controls.Add(new LiteralControl(" report.reportId.ToString ()"));
// Create Hyperlink Web Server control and add to cell
System.Web.UI.WebControls.HyperLink h = new HyperLink();
h.Text = reportTable.Rows[i].Cells[1].Text = report.reportId.ToString();
h.NavigateUrl = "~/manage.aspx";
tCell.Controls.Add(h);
reportTable.Rows[i].Cells[2].Text = bench.mechId;
reportTable.Rows[i].Cells[3].Text = bench.elecId;
reportTable.Rows[i].Cells[4].Text = bench.name;
asp.net Grid and data controls are very good for data binding.
Also they provide Item templates that can be customized to include links, drop down lists, etc.
Do not populate your grid by manually creating all the controls. That totally defeats the purpose of using a grid.
e.g:
<asp:GridView ID="ReportsGridView"
DataSourceID="ReportsDataSource"
AllowPaging="true"
AutoGenerateColumns="false"
runat="server">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton runat="server"
ID="RedirectButton"
CommandName="Manage"
PostBackUrl="~/manage.aspx"
Text="Manage" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Name"
HeaderText="Report Name"/>
</Columns>
</asp:GridView>