Can I build a control that basically acts "like a MasterPage"?
What I mean to do is, say I have a grid like this in a number of pages:
<asp:UpdatePanel ID="AnnouncementsPanel" UpdateMode="Conditional" runat="server">
<ContentTemplate>
<asp:GridView ID="AnnoucementsGrid" runat="server" AutoGenerateColumns="false" DataKeyNames="Id" >
<Columns>
<asp:BoundField DataField="Title" HeaderText="Title" />
<asp:BoundField DataField="Created" HeaderText="Date" />
<asp:BoundField DataField="Modified" HeaderText="Last Modified" />
<asp:ButtonField ButtonType="Button" Text="Process" CommandName="Process" />
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
I'd like to build a control that handles most of the codebehind, but I need to declare the columns for the grid declaratively in each case.
Is there a way to create a control like this?
<uc:CrudGrid ID="AnnouncementsCrud" runat="server">
<Columns>
<asp:BoundField DataField="Title" HeaderText="Title" />
<asp:BoundField DataField="Created" HeaderText="Date" />
<asp:BoundField DataField="Modified" HeaderText="Last Modified" />
<asp:ButtonField ButtonType="Button" Text="Process" CommandName="Process" />
</Columns>
</uc:CrudGrid>
or event better:
<uc:CrudGrid ID="AnnouncementsCrud" runat="server">
<Columns>
<asp:BoundField DataField="Title" HeaderText="Title" />
<asp:BoundField DataField="Created" HeaderText="Date" />
<asp:BoundField DataField="Modified" HeaderText="Last Modified" />
</Columns>
</uc:CrudGrid>
Maybe having to name the tag "Fields", but being able to drop the button, so it can be used in the UC's code-behind?
A lot of love to whoever has a positive answer on this <3
Found the exact solution I was looking for:
[DefaultValue((string)null)]
[Editor(typeof(System.Web.UI.Design.WebControls.DataControlFieldTypeEditor), typeof(UITypeEditor))]
[PersistenceMode(PersistenceMode.InnerProperty)]
public DataControlFieldCollection Columns
{
get { return Grid.Columns; }
}
this way I can expose the Columns from the grid in my own user control and edit the fields from the markup, keeping general functionalities within my UC
Depends on how positive you want it to be :-) You can always build your own control to do this. That is one option.
Another option is to create a helper object that attaches to the grid, and keep each grid separate.
Third option is to create a user control with the common code, and programmably add columns to the grid through the user control.
HTH.
Related
I have a gridview with some values. If the user clicks on a link or button (here I took a Buttonfield with the text 'Copy') on one of the rows, it should copy a cell value of that row to the clipboard.
Is something like this possible in asp.net c# ?
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="id" DataSourceID="SqlDataSource1" Visible="False" OnRowDataBound="GridView1_RowDataBound"
onselectedindexchanged="GridView1_SelectedIndexChanged1">
<Columns>
<asp:BoundField DataField="Username" HeaderText="Username"
SortExpression="Username" />
<asp:BoundField DataField="Password" HeaderText="Password"
SortExpression="Password" />
<asp:CommandField ButtonType="Image" EditImageUrl="/images/edit.png" CancelImageUrl="/images/undo.png" UpdateImageUrl="/images/save.png" ShowEditButton="True" />
<asp:CommandField ButtonType="Image" ShowDeleteButton="True" DeleteImageUrl="/images/deletered.png" />
<asp:ButtonField Text="Copy" />
</Columns>
<EmptyDataTemplate>
No data available
</EmptyDataTemplate>
</asp:GridView>
There is no Onclick event available for a ButtonField. Otherwise I would think of using some javascript (I have seen that in other solutions)
Thanks for any input.
You can do that with windows form only, but since you are working on Web application you should write client side code which is javascript to copy data on client side not server side. checkout this link
I have this:
<uc:MyCustomGridView runat="server">
</uc:MyCustomGridView>
This is an UserControl which is not only a GridView. It has some other controls, like a menu bar on top, and a title.
I would like to create a GridView inside my MyCustomGridView like this:
<uc:MyCustomGridView runat="server">
<uc:MyCustomGridView.GridView>
<Columns>
<asp:BoundField HeaderText="Code" DataField="Code" />
<asp:BoundField HeaderText="Description" DataField="Description" />
</Columns>
</uc:MyCustomGridView.GridView>
</uc:MyCustomGridView>
Is something like this possible? Is there any keyword that I should search for?
I solved by reading the following tutorial:
http://www.tomot.de/en-us/article/2/asp.net/how-to-create-an-asp.net-control-that-behaves-as-a-template-container-to-nest-content-via-markup
I have the following GridView:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="SysInvoiceID" DataSourceID="SqlDataSource1">
<Columns>
<asp:BoundField DataField="InvoiceID" HeaderText="SysInvoiceID" ReadOnly="True" SortExpression="SysInvoiceID" />
<asp:BoundField DataField="BillMonth" HeaderText="BillMonth" SortExpression="BillMonth" />
<asp:BoundField DataField="InvoiceDate" HeaderText="InvoiceDate" ReadOnly="True" SortExpression="InvoiceDate" />
<asp:BoundField DataField="InvoiceNumber" HeaderText="InvoiceNumber" SortExpression="InvoiceNumber" />
<asp:BoundField DataField="Net" HeaderText="Net" SortExpression="Net" />
<asp:BoundField DataField="VAT" HeaderText="VAT" SortExpression="VAT" />
<asp:BoundField DataField="Gross" HeaderText="Gross" SortExpression="Gross" />
<asp:ButtonField CommandName="ViewInvoice" HeaderText=" " ShowHeader="True" Text="View" />
</Columns>
</asp:GridView>
The very last column (ButtonField) is one I created myself just to include the text 'View' on each row, which when clicked, will bring up a PDF invoice.
I'm not sure if this is even possible, but I was wondering if it was possible to add some sort of validation for that column or something, so that if the 'InvoiceID' column is blank, the 'View' link on the corresponding row won't show up.
I felt close to doing this by going on split view in Visual Studio and then the 'Edit Columns' button on GridView tasks, but like I said I'm not sure if it's possible to do it this way and may have to resort to simply coding it.
Thanks for any help!
Use a <TemplateField> instead of a <ButtonField>
<asp:TemplateField>
<ItemTemplate>
<asp:Button runat="server" Text="View"
Visible='<%# Eval("IsEmpty(InvoiceID)") %>' CommandName="ViewInvoice" />
</ItemTemplate>
</asp:TemplateField>
And add a method to your page that is IsEmpty(string id) or whatever type your id is, and just check to see if it's empty first.
You can also add a CommandArgument attribute to the Button that will let you specify what the argument to it will be.
Use a placeholder...
<asp:Placeholder runat="server" ID="plView" Visible="<%# Convert.ToBoolean(InvoiceID == null) ? false : true %>">
<asp:ButtonField CommandName="ViewInvoice" HeaderText=" " ShowHeader="True" Text="View" />
</asp:Placeholder>
Well it so happens that I am kind of a novice to asp.net and trying to create a Grid whose source is declared programmatically.
In the process, I came across 2 tags Fields and Columns. Can anyone please tell me how they are different?
EDIT: I went through some sample MSDN examples, and for all I can tell it seems to me they can be used interchangeably(though I have a feeling thats not true!).
Check this out:
<asp:GridView ID="GridView1" runat="server"
AutoGenerateColumns="False" DataKeyNames="EmployeeID" DataSourceID="ObjectDataSource1">
<Columns>
<asp:BoundField DataField="LastName" HeaderText="LastName"
SortExpression="LastName" />
<asp:BoundField DataField="FirstName" HeaderText="FirstName"
SortExpression="FirstName" />
<asp:BoundField DataField="Title" HeaderText="Title"
SortExpression="Title" />
<asp:BoundField DataField="HireDate" HeaderText="HireDate"
SortExpression="HireDate" />
</Columns>
</asp:GridView>
And then there is:
<asp:GridView ID="GridView1" runat="server" AllowPaging="True"
AutoGenerateRows="False" DataKeyNames="ProductID"
DataSourceID="ObjectDataSource1" EnableViewState="False">
<Fields>
<asp:BoundField DataField="ProductName" HeaderText="Product"
SortExpression="ProductName" />
<asp:BoundField DataField="CategoryName"
HeaderText="Category"
ReadOnly="True" SortExpression="CategoryName" />
<asp:BoundField DataField="SupplierName"
HeaderText="Supplier"
ReadOnly="True" SortExpression="SupplierName" />
<asp:BoundField DataField="QuantityPerUnit"
HeaderText="Qty/Unit" SortExpression="QuantityPerUnit" />
<asp:BoundField DataField="UnitPrice"
DataFormatString="{0:c}"
HeaderText="Price"
HtmlEncode="False" SortExpression="UnitPrice" />
</Fields>
</asp:GridView>
Seem similar or is it just me??!
Thanks for helping.
Columns is just the surrounding tag for the fields which are
TemplateFields with any controls you want or
BoundFields which are created automatically
So Columns enclose the list of fields in the GridView.
<Columns>
<asp:Boundfield datafield="StudentID"
readonly="true"
headertext="Student ID"/>
<asp:TemplateField HeaderText="Student" HeaderStyle-HorizontalAlign="Left">
<ItemTemplate>
<asp:label runat="server" Font-Bold="true" ID="LblStudent" Text='<%# Bind("Student") %>'></asp:label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Inner Grid">
<ItemTemplate>
<asp:GridView ID="Grid2" AutoGenerateColumns="false" runat="server" GridLines="None" Width="300">
<RowStyle CssClass="GridViewRowStyle" />
<AlternatingRowStyle CssClass="GridViewAlternatingRowStyle" />
<HeaderStyle CssClass="GridViewHeaderStyle" />
<SelectedRowStyle BackColor="Aqua" />
<Columns>
<asp:TemplateField HeaderText="Student" HeaderStyle-HorizontalAlign="Left">
<ItemTemplate>
<asp:label runat="server" Font-Bold="true" ID="LblStudent" Text='<%# Bind("Student") %>'></asp:label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ItemTemplate>
</asp:TemplateField>
</Columns>
As you can see, a TemplateField could also contain another nested GridView.
Am I blind or wat!
After I posted this question I went back to my drawingboard and as it turns out, there is no Fields tag in asp:GridView, right?!
Please do let me know if this is true people(and prove me silly!)
Putting aside this particular control for a moment, it might be helpful to look at this from a general computer science point of view.
In classic programming (ANY LANGUAGE), a FIELD would be the INTERSECTION of a row and a column -- a discrete piece of data. For example, if a table has 20 rows of data containing first and last names, if you went to the 19th row and looked in the "first name" column, you've got a FIELD. Perhaps it contains the discrete data "JOHN".
COLUMNS then would be collections of like data -- in this example, you have the two columns "first name" and "last name". Columns would have attributes such as a data type, maximum length, constraints (are nulls OK?, etc.) and so forth.
Some may quibble with my definitions and say that individual cells in a COLUMN would be called a FIELD. It's not uncommon to hear that. I would reply that for a table with a single column, it'd be especially true :-) But the takeaway point is this: COLUMNS are generally containers for smaller, more discrete items such as FIELDS. FIELDS typically refer to a single piece of data, such as you'd find at the intersection of a row and column in a database table.
On my page there are textboxes which I use for input. How can I wire those textboxes to an EntityDataSource control?
Instead of using plain text boxes with your EntityDataSource control, I would recommend using a GridView control with a corresponding DetailsView control. The EntityDataSource control was designed to work nicely with these two controls. The DetailsView control will be the one which is actually responsible for the inserting and updating of your data.
When you are configuring the EntityDataSource controls (you will need two, one for the GridView and one for the DetailsView), make sure to check the 'Enable automatic inserts,' 'Enable automatic updates,' and 'Enable automatic deletes' check boxes in the 'Configure Data Selection' screen of the setup wizard. In your case, since you are only interested in inserting the data, you can just check the 'Enable automatic inserts' checkbox.
You can also just use the DetailsView by itself, and leave the GridView out. To do this, you'll need to configure the DetailsView's EntityDataSoruce 'Expression Editor' for the 'Where' clause a bit differently (found in the properties list of the EntityDataSource control).
It's important to point out that the GridView and DetailsView are pretty heavy controls. Unless you are building a small site (with few users) or prototyping a planned site project, I would recommend revising your development strategy and possibly going with raw ADO.Net instead.
Here is a simple example:
<asp:EntityDataSource ID="EntityDataSource1" runat="server"
ConnectionString="name=SomeDatabaseEntities"
DefaultContainerName="SomeDatabaseEntities"
EnableFlattening="False"
EntitySetName="Links" EnableDelete="True" EnableInsert="True"
EnableUpdate="True">
</asp:EntityDataSource>
<asp:GridView ID="GridView1" runat="server" CellPadding="4"
ForeColor="#333333"
GridLines="None" AllowPaging="True" AllowSorting="True"
EnableViewState="false"
DataSourceID="EntityDataSource1"
AutoGenerateColumns="False" PageSize="20"
DataKeyNames="LinkId">
<Columns>
<asp:CommandField ShowDeleteButton="True"
ShowSelectButton="True" />
<asp:BoundField DataField="LinkId" HeaderText="LinkId"
SortExpression="LinkId" ReadOnly="True" />
<asp:BoundField DataField="Title" HeaderText="Title"
SortExpression="Title" />
<asp:BoundField DataField="URL" HeaderText="URL"
SortExpression="URL" />
<asp:BoundField DataField="ImagePath" HeaderText="ImagePath"
SortExpression="ImagePath" />
</Columns>
</asp:GridView>
<br />
<asp:EntityDataSource ID="EntityDataSource2" runat="server"
ConnectionString="name=SomeDatabaseEntities"
DefaultContainerName="SomeDatabaseEntities"
EnableFlattening="False"
EntitySetName="Links" Where="it.LinkId == #LinkId"
EnableInsert="True"
EnableUpdate="True">
<WhereParameters>
<asp:ControlParameter ControlID="GridView1"
DbType="Int32" Name="LinkId"
PropertyName="SelectedValue" />
</WhereParameters>
</asp:EntityDataSource>
<asp:DetailsView ID="DetailsView1" runat="server" Height="50px"
Width="125px"
CellPadding="4" ForeColor="#333333"
GridLines="None" DataKeyNames="LinkId"
AutoGenerateRows="False"
DataSourceID="EntityDataSource2">
<Fields>
<asp:BoundField DataField="LinkId"
HeaderText="LinkId"
ReadOnly="true" InsertVisible="false"
SortExpression="LinkId" />
<asp:BoundField DataField="Title"
HeaderText="Title"
SortExpression="Title" />
<asp:BoundField DataField="URL" HeaderText="URL"
SortExpression="URL" />
<asp:BoundField DataField="ImagePath"
HeaderText="ImagePath"
SortExpression="ImagePath" />
<asp:CommandField ShowEditButton="True"
ShowInsertButton="True" />
</Fields>
</asp:DetailsView>