I am attempting what I think is a rather simple databinding scenario with Linq To SQL.
I have a table of FacultyMembers, whose schema looks something like this:
FacultyMemberID - int PK
Name - nvarchar
UniversityID - int FK to University table
and so forth. There are various other string properties.
I generate LTS DataClasses. I drop a LinqDataSource and a GridView on a page, enable update and delete for both, and I'm on my merry way. No code, and I'm able to update my string properties. A little manipulation with a DropDownList on the UniversityID and I'm able to update that one-to-many relationship, too. Yay.
Now, lets say I throw in a many-to-many mapping table. Let's say DivisionMemberships, which maps FacultyMembers to Divisions. DivisionMembership uses the simple and obvious schema:
FacultyMemberID - int PK, FK to FacultyMembers table
DivisionID - int PK, FK to Divisions table
Now, when I take a row of my GridView into EditMode, I run into a problem because I don't know how to update the many-to-many relationship. I mucked around with a few alternatives, and right now I'm trying to get a ListView to work in there. I'm doing something like this:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
AllowPaging="True" AllowSorting="True" PageSize="25" DataKeyNames="FacultyMemberID" >
<Columns>
<asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
<asp:TemplateField HeaderText="University" SortExpression="UniversityID">
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("University.Name") %>' />
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="DropDownList2" runat="server"
DataSourceID="LinqDataSourceUniversities" DataTextField="Name"
DataValueField="UniversityID" SelectedValue='<%# Bind("UniversityID") %>'>
</asp:DropDownList>
<asp:LinqDataSource ID="LinqDataSourceUniversities" runat="server"
ContextTypeName="NYDERHE.NYDERHEDataClassesDataContext"
Select="new (UniversityID, Name)" TableName="Universities">
</asp:LinqDataSource>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Division">
<EditItemTemplate>
<asp:ListView ID="ListView1" runat="server"
InsertItemPosition="LastItem" DataSource='<%# Eval("DivisionMemberships") %>'><ItemTemplate>
<li style="">FacultyMemberID:
<asp:Label ID="FacultyMemberIDLabel" runat="server"
Text='<%# Eval("FacultyMemberID") %>' />
<br />
DivisionID:
<asp:Label ID="DivisionIDLabel" runat="server"
Text='<%# Eval("DivisionID") %>' />
<br />
Division:
<asp:Label ID="DivisionLabel" runat="server" Text='<%# Eval("Division") %>' />
<br />
FacultyMember:
<asp:Label ID="FacultyMemberLabel" runat="server"
Text='<%# Eval("FacultyMember") %>' />
<br />
<asp:Button ID="DeleteButton" runat="server" CommandName="Delete"
Text="Delete" />
</li>
</ItemTemplate>
</asp:ListView>
</EditItemTemplate>
and so forth. Some of the chatter above is removed, but ListView is pretty verbose as-is, so I don't want to overload the page.
Things to note here:
For my University association, I use a new LinqDataSource and query for items WHERE the UniversityID matches, then bind the new UniversityID (DDL value) to the FacultyMember, whereas for the DivisionMemberships, I bind directly to the property (as described here)
I use DataBinder.Bind() for UniversityID, whereas I use DataBinder.Eval() for DivisionMemberships.
If I switch to Bind() for DivisionMemberships, I get a NotSerializableException for EntitySet. If I stick with Eval(), I have to write the OnDelete and OnInsert methods for the ListView myself, and I don't want to Delete or Insert the DivisionMemberships until the entire FacultyMember row exits EditMode. I'd probably create a DataContext and stick it in the session for this, because I don't have another way to mark the DivisionMemberships for updates.
I would think that this scenario would be pretty easy to enable out of the box, but I'm lost. Any advice on where to go from here? Specifically, should I wrestle with Bind() and try to make EntitySet serializable, should I bite the bullet and write the somewhat hackish code described above for storing a DataContext in session until the OnRowUpdating event fires, or am I going the wrong way completely?
You're right, it is long, but kudos on including some code, JIC.
It does seem apparent that you're not going to be able to do this with ordinary DataBinding. I'm not too keen on storing this in session, but I do understand that you don't want a postback.
What you might want to do is set up an Ajax call so that you can stick your new record (or your record change) into the DataContext. When the form is submitted, you can call SubmitChanges on the DataContext.
Seems to me Josh that trying to manage your many-to-many relationship from within the Faculty Member grid is not the right approach.In fact, I can't really visualise how this would work inside a grid, I am not surprised that you are lost :)
Better to use a 'detail' page where the context is = to a single Faculty member and provide a 'double list' interface for division membership maintenence. This would consist of 2 lists.
The righthand list shows all the divisions to which the faculty member is already a member(DivisionMembership rows where FacultymemberId = the context id) , the left hand list would show all the remaining Divisions. You could then provide '>>' and '<<' buttons in between the lists to add/remove the Faculty member from the divisions (Inserting/deleting DivisionMemberships rows)
Michael
Related
I'm using a ASP:Linkbutton with some CSS inside a ASP:Gridview and I was able to get it inserted but cannot get it centered in the column. The code I'm running is:
<asp:TemplateField HeaderText="Modify" ItemStyle-Width="1px" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:LinkButton ID="cmdModifyUser" runat="server" CssClass="ovalbutton">
<span>
Modify
</span>
</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Delete" ItemStyle-Width="1px">
<ItemTemplate>
<asp:LinkButton ID="cmdDeleteUser" runat="server" CssClass="ovalbutton">
<span>
Delete
</span>
</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
This code is encapsulated after my last /asp:BoundField and before /Columns inside my /asp:Gridview .
When this is run, it looks like this:
I'm trying to get those buttons centered in the column.
I've tried as much HTML as I could find to try to center this but with no luck.
Also, you'll notice the code of ItemStyle-Width:1px in there too. If I don't put that in, or something like it, I get this:
Thank you for your help & let me know if you need anymore information.
I have a grid view that populates two columns. One with the name of a file and the other with a path that links to a pdf.
<asp:GridView ID="Grid" runat="server" AutoGenerateColumns="false" Font-Names="Arial"
Font-Size="11pt" AlternatingRowStyle-BackColor="#C2D69B" HeaderStyle-BackColor="green"
AllowPaging="false" PageSize="10" OnRowDataBound="Grid_RowDataBound">
<Columns>
<asp:BoundField ItemStyle-Width="80%" DataField="Name" HeaderText="Name"></asp:BoundField>
<asp:hyperlinkfield headertext="PDF" datatextfield="PDF" datanavigateurlfields="PDF" datanavigateurlformatstring="" text="PDF" />
</Columns>
</asp:GridView>
I have tried renaming the field to say "PDF" rather than displaying that documents path. How can I have it be show "PDF" on the webpage rather than displaying the document path to the user?
Remove the DataTextField attribute and it will use the Text attribute as link text.
<asp:HyperLinkField HeaderText="PDF" DataNavigateUrlFields="PDF" Text="Download PDF" />
Basically, I have a "Posts" DataTable with multiple rows.
Each row contains fields like "UserID", "PostBody", "PostDate", "UploadedFileID" etc.
What I'm trying to achieve is a "News" page, where users can see all the posts from the DataTable.
So if I have 5 rows, i want for each row to have an HTML Structure like:
<div id="post">
<h3>User name (based on the UserID row)</h3>
<div id="postBody">
bla bla bla whatever the user posted
</div>
<a href="(link to the posted file)">
<img src="something" />
</a>
</div>
I'm thinking that inside the .aspx file, in the PageLoad event I have to make a while loop, like:
while (there are posts in the posts table)
write html;
How do I add HTML-building conditions, and more importantly, paging?
Thanks,
Tudor.
You could use one of the several data binding controls and put your html structure into the template.
Refer: Asp.net DataBound controls
Ones like the Repeater or ListView should give you what you want.
<asp:ListView runat="server" ID="ListView1"
DataSourceID="PostsDataSource" >
<ItemTemplate>
<div id="post">
<h3>User name (based on the UserID row)</h3>
<div id="postBody">
<asp:Label ID="LastNameLabel" runat="Server"
Text='<%#Eval("PostBody") %>' />
</div>
<a href="(link to the posted file)">
<img src="something" />
</a>
</div>
</ItemTemplate>
</asp:ListView>
Code behind:
ListView1.DataSource =
The advantage of using a data binding control is that asp.net will manage the paging and value binding.
I used the ajax's slider extender control in my web page. I want to reduce the length of the control.
How should i show the rail track on the control or below the control depending on the steps of the control?
How should i set length of the control?
If it is possible then provide some document related on this topic.
I used the control in following way...
<asp:TextBox ID="txtPercentageCompleted" runat="server" Text="0" Width="100%" style="display:none;"
ontextchanged="txtPercentageCompleted_TextChanged" AutoPostBack="true"></asp:TextBox>
<ajaxToolkit:SliderExtender ID="SliderExtender1" runat="server" BehaviorID="txtPercentageCompleted"
TargetControlID="txtPercentageCompleted"
Minimum="0"
Maximum="100"
BoundControlID="lblPercentage"
Steps="5" EnableHandleAnimation="true">
</ajaxToolkit:SliderExtender>
<asp:Label ID="lblPercentage" runat="server" Text="Label" Width="100%"></asp:Label>
I've solved one of above issue that is Setting size of the rail track of slider extender contrl-
<asp:TextBox ID="txtPercentageCompleted" runat="server" Text="0" Width="100%" style="display:none;"
ontextchanged="txtPercentageCompleted_TextChanged" AutoPostBack="true"></asp:TextBox>
<ajaxToolkit:SliderExtender ID="SliderExtender1" runat="server" BehaviorID="txtPercentageCompleted"
TargetControlID="txtPercentageCompleted"
Minimum="0"
Maximum="100"
BoundControlID="lblPercentage"
Steps="5" EnableHandleAnimation="true"
RailCssClass="sliderrail"
Orientation = "Horizontal">
</ajaxToolkit:SliderExtender>
<span style="float:left;width:8%;text-align:right;"> <asp:Label ID="lblPercentage" runat="server" Text="Label" Width="100%"></asp:Label></span>
Css of the sliderrail is-
.sliderrail
{
position:relative;
background-image:url('../images/slider_h_rail.gif');
height:22px;
width:100px;
}
Also there is Length property present to the slider control. By using we can set width/height of control and is depend on the orientation property that is horizontal or vertical.
You could try to contain the control within a div with a width.
Or
You could view the output html that is produced and attempt to create css to limit the length. That is if you can create a selector based on any client Ids or similar.
I am trying create a table and add this table into tablecell (table inside table in short)
It seems to be working with pure html and Javascript but it does not seem to work with asp.net table. I have tried to add other controls to the particular cell, like adding labels, htmldiv, textboxes and they all work fine except table.
Does anyone how to to achieve this by any chance?
If i understand you right here is an example:
<asp:Table runat="server">
<asp:TableRow>
<asp:TableCell>
<asp:Table runat="server">
</asp:Table>
</asp:TableCell>
</asp:TableRow>
</asp:Table>