erkaMedlem sedan dec. 19996 522 inlägg Hej!
Sitter å har börjat kika på Calendar och har lite funderingar om det. Jag ska försöka binda data från en tabell i en db med aktivteter. (MSSQL2000)
Eftersom jag inte vill hämta info från data db:n varje gång dayrender sker så borde man ju kunna hämta ut det och lagra informationen direkt på toppen av sidan, för att sedan hämta ut den infon så att säga i kalendern. Vad jag vill göra är om det finns en aktivitet på datumet ska det skrivas med fettext, och om man trycker på ett datum där det finns en aktivitet ska datumet skrivas ut nedanför kalenderna och sedan loopa igenom aktiviteterna som finns på den dagen.
Då återstår ett problem, vilket sätt är det smidigaste att lösa detta på och hur gör man det :) Någon som har några tankar / erfarenheter.
Tacksam!
renholmMedlem sedan apr. 20012 266 inlägg erkaMedlem sedan dec. 19996 522 inlägg Ok jag har kikat där, vilken form passar bäst att lägga min data i? Jag hämtar ut 5 st kolumner för varje aktivitet, i klassisk asp hade ju ja släng det i en 2 dimensionell array och loopat igenom den, men om jag ska slänga in den i en sådan array nu och loopa igenom den så fort OnDayRender körs så blir det ju en jvla massa loopande. Vad tjänar jag på att lägga det i en DataSet istället
erkaMedlem sedan dec. 19996 522 inlägg Okej jag hade tänkt att göra så här.
1. Jag börjar å kolla om sidan är PostBack:ad eller inte, är den inte det fyller jag en DataSet med alla aktiviteter i db som har samma månadsnummer som vi är i. Sen kör jag på OnVisibleMonthChanged att man ska skriva om min dataset med den månadens nr.
Men för att kolla om han har bytt månad måste jag ju få ut månadsnummret i det datum som han har klickat på.
Fråga nr1.
Hur får jag ut månadsnummret, ifrån det datum man klickar på.
Fråga nr2.
Vilket leder mig direkt till fråga nr2. Jag ska på OnDayRender lista ut de "poster" i DataSet som hör till klickat datum, i DataSet har jag ju alla som hör till vald månad och inte vald dag. För om jag hämtar ut från db:n dag till dag så att säga så blir det ju förbaskat många anrop.
Tacksam som vanligt om någon hjälper mig i djungeln :) Har kollat på en del exempel på https://www.asp.net och 4guys men inte riktigt lyckats klura ut hur jag ska anpassa det. Stor tack på förhand till den som känner att han har ork
NETworkMedlem sedan juni 20011 732 inlägg Fråga nr1.
Hur får jag ut månadsnummret, ifrån det datum man klickar på.
Calendar.SelectedDate.Month
Fråga nr2.
Vilket leder mig direkt till fråga nr2. Jag ska på OnDayRender lista ut de "poster" i DataSet som hör till klickat datum, i DataSet har jag ju alla som hör till vald månad och inte vald dag. För om jag hämtar ut från db:n dag till dag så att säga så blir det ju förbaskat många anrop.
Om du lägger ditt dataset i en dataview så kan du använda metoden rowfilter. Den kan du kan använda för att plocka ut det du vill ha fram ur din dataview, ungefär som att skicka in en sql-sats till din dataview istället för att anropa databasen. Något sånt här kanske:
DataView dv = new DataView(ds);
dv.RowFilter = "Datum = '" + Calendar.SelectedDate + "'";
erkaMedlem sedan dec. 19996 522 inlägg Tack så mycket Network, skönt å få hjälp innan man greppat det själv, det lär ju ta ett tag oxå, he he..
Ok sista hjälpen jag behöver på ett tag hoppas jag, sen ska det nog rulla på. Inga frågor är för dumma brukar det heta, har förbannat svårt att stänga av det "klassisk asp" sättet att hantera data från db på sidorna.
1. Eftersom jag hämtar ut en månads aktiviteter i taget, slänger det i en dataview. Klickar jag på ett datum ska den ju filtrera bort de aktiviteter som inte hör till klickat datum, hur skriver jag ut dem på sidan. Jag har en asp calendar kontroll och det är under den jag vill skriva ut aktiviteterna. Det sköts ju av dayrender och ska ligga i en sub som inträffar på varje dayrender.
Sen undrar jag exakt när onSelectionChange inträffar? och vad man behöver köra i den, som jag har förstått det är det när man klickar på ett datum så körs den, medans dayrender sker när man skriver ut kalenderkontrollen.
Stort tack för hjälpen hitills.
Tacksam!
erkaMedlem sedan dec. 19996 522 inlägg Man slänger det i en datagrid eller
Redigering:
Stötte på patrul igen, om jag i on_load slänger in alla måndadens aktuella datum i en DataSet, dumpar in dem i en dataview, stänger sedan connection och så. Kan jag isåfall i Sub_OnDayRender filtrera min dataview jag skapade i suben som körs vi on_load, har inte lyckats med det nämligen
Tack!
NETworkMedlem sedan juni 20011 732 inlägg Det är inga problem att fylla en datagrid med din dataview:
myDataGrid.DataSource = dv;
Jag har en asp calendar kontroll och det är under den jag vill skriva ut aktiviteterna. Det sköts ju av dayrender och ska ligga i en sub som inträffar på varje dayrender.
Jag vet inte riktigt om jag förstått dig rätt nu och vad du försöker göra. Alltså, om du klickar på en dag i kalendern och du vill ha aktiviteterna för bara den aktuella dagen så skulle jag inte krånglat till det mer än att jag öppnar en connection mot min db och hämtar alla rader för den aktuella dagen.
Dayrendern använder du för att gå igenom dag för dag i din kalenderkontroll, en loop alltså. Finns flera finesser du kan använda i denna, exempelvis med "isothermonth" så kan du se till att den bara kör kod för den aktuella månaden och ingenting annat:
CalendarDay d = ((DayRenderEventArgs)e).Day;
if (!d.IsOtherMonth) {
// Din kod här
}
Men nej, du ska inte använda dayrendern för att skriva ut aktiviteter för en specifik dag, dayrendern använder vanligtvis du om du behöver gå igenom dag för dag och förändra något inne i din kalenderkontroll, inte utanför den. Exempelvis om du vill lägga en speciell bakgrundsfärg, en text etc på de datum i kalendern som innehåller något i din databas.
Alltså, ska du hämta aktiviteter för en enskild dag från ett valt datum i din kalender skapar du en egen funktion för detta.
protected void GetActivities(object sender, System.EventArgs e) {
DateTime SelectedDate = Calendar1.SelectedDate;
// hämta från db och fyll en datagrid!
}
//I din kalender:
<asp:calendar id=Calendar1 OnSelectionChanged="GetActivities" runat="server">
NETworkMedlem sedan juni 20011 732 inlägg
erka skrev:
Man slänger det i en datagrid eller
Redigering:
Stötte på patrul igen, om jag i on_load slänger in alla måndadens aktuella datum i en DataSet, dumpar in dem i en dataview, stänger sedan connection och så. Kan jag isåfall i Sub_OnDayRender filtrera min dataview jag skapade i suben som körs vi on_load, har inte lyckats med det nämligen
Tack!
Japp, men för att nå din instans av din dataview så måste den vara public (eller så får du använda accessors). Men om jag inte missat dig nu så föreslår jag alltså att du glömmer bort både dayrendern och dataviewn om du bara ska hämta data för en enskild dag, det kan du göra precis lika bra och (nästan) lika snabbt direkt från din db. :)
erkaMedlem sedan dec. 19996 522 inlägg STORT Tack för en hel del utömmande svar Network återkommer med mer frågor i morgon bergis, nu ska jag plugga körkortsteori för jag skriver upp i morgon :)
erkaMedlem sedan dec. 19996 522 inlägg Kom på en fråga medans jag käkade :)
1. Kan man på något sätt få kalendern att inte skriva ut endast de datumen som finns i den månaden man är i, och skippa de från tidigare och nästa månad. Isåfall skulle man ju enkelt kunna slänga in alla månadens aktiviteter i en dataview och skriva ut datumen med fettext där det finns en aktivitet.
Jag har letat febrilt överallt efter hur man får den att endast skriva ut den aktuella månadens dagar och då givetvis behålla länkarna till nästa och föregående månad
NETworkMedlem sedan juni 20011 732 inlägg Javisst. Du använder vb? Om du kör den här koden i din dayrender så kommer den att att radera alla kontroller (dagar) utanför den aktuella månaden:
Dim d as CalendarDay
Dim c as TableCell
d = e.Day
c = e.Cell
If d.IsOtherMonth Then
c.Controls.Clear
erkaMedlem sedan dec. 19996 522 inlägg Tack så mycket för hjälpen NETwork. Jag har nu kommit så långt att jag har en rätt fungerande kalender där man får ut dagens aktiviteter om man trycker på den, jag lägger den månad man är på i en dataview och sen sorterar jag det med rowfilter på datumet man trycker på. Ska bara fixa lite cachning etc senare.
Nu binder jag min dataview till en datagrid och har stött på problem.
Jag hämtar ut följande kolumner och har dem i min dataview
-Pk_ActivityId
-Fk_UsrId
-ActivityDate
-ActivityHeader
-ActivityContent
-UsrFirstName
-UsrSurName
När jag skriver ut dem i min datagrid blir det ju exakt som en tabellfrån en databas (antar att det är meningen men...) jag vill ha formaterin på ett annat sätt Jag vill skriva ut dagens aktiviteter på följande sätt,
ActivityHeader<br>
ActivityContent<br><br>
Inlaggd av: Här skapar jag en länk till användaren som lagt in aktiviteten (baserad på UsrFirstName, UsrSurName,Fk_UsrId)
Jag vet att det går att grejja med en reader, men då missar jag ju hela min sortering och att jag enbart plockar ut månadens data. Så min fråga är alltså, ska jag skippa datagrid och koncentrera mig på att binda min dataview till något annat, eller ska jag "customiza" min datagrid.
Respect !
;)
erkaMedlem sedan dec. 19996 522 inlägg Har bytt till att visa datat för dagen i en DataList istället för en DataGrid, för att kunna formatera datan smidigt och exakt som jag vill.
Jag har läst att man inte ska använda en datalist på följande sätt
<asp:DataList ID="LLCalenderList" Runat="server"
cssClass="BrodTextIndrag"
Width="192"
BorderWidth ="0"
ShowHeader = "False"
>
<ItemTemplate>
<b><%# DataBinder.Eval(Container.DataItem, "ActivityHeader") %></b><br>
<%# DataBinder.Eval(Container.DataItem, "ActivityContent") %><br>
<a href="User/VisaAnvandare.asp?IntUsrId=<%# DataBinder.Eval(Container.DataItem, "Fk_UsrId") %>"><%# DataBinder.Eval(Container.DataItem, "UsrFirstName") &" "& DataBinder.Eval(Container.DataItem, "UsrSurName") %></a>
<br><br>
</ItemTemplate>
</asp:DataList>
Detta ska tydligen bli långsamt, men hur löser man det på ett annat sätt med datalist, känner att jag är på rätt väg nu :) he he he
erkaMedlem sedan dec. 19996 522 inlägg Eftersom sättet jag visar datalisten ovan funkar så kör jag på det för tillfället. Dock har jag upptcäkt att jag inte lyckas göra min dataview public.
<script language="Vb" runat="server">
Public IntMonthNo as String
Public myDataSet AS DataSet
Public MyDataview AS Dataview
Public strConn As String = "server=xxxxxxxx ;database=xxxxxxx;uid=IUSR_LL; pwd=xxxxxxx"
Sub Page_Load(sender As Object, e As EventArgs)
If Not Page.IsPostBack then
Dim CurrentDate as DateTime
CurrentDate = DateTime.Now()
IntMonthNo = CurrentDate.Month
GetEvents(IntMonthNo)
MyDataview.RowFilter = "ActivityDate = '" + LLCalendar.SelectedDate + "'"
LLCalenderList.DataSource = MyDataView
LLCalenderList.DataBind()
End If
End Sub
Sub LLCalendar_OnSelectionChange(sender As Object, e As EventArgs)
MyDataview.RowFilter = "ActivityDate = '" + LLCalendar.SelectedDate + "'"
LLCalenderList.DataSource = MyDataView
LLCalenderList.DataBind()
End Sub
Sub LLCalendar_VisibleMonthChanged(s as Object, e as MonthChangedEventArgs)
IntMonthNo = e.NewDate.Month
GetEvents(IntMonthNo)
End Sub
Sub LLCalendar_DayRender(o as object ,e as DayRenderEventArgs)
Dim d as CalendarDay = e.Day
Dim c as TableCell = e.Cell
If d.IsOtherMonth Then
c.Controls.Clear
End If
End Sub
Function GetEvents(IntMonthNo)
Dim strSQL As String = String.Format("SELECT dbo.LL_activitys.Pk_ActivityId, dbo.LL_activitys.Fk_UsrId, dbo.LL_activitys.ActivityDate, dbo.LL_activitys.ActivityHeader, dbo.LL_activitys.ActivityContent, dbo.LL_users.UsrFirstName , dbo.LL_users.UsrSurName FROM dbo.LL_activitys INNER JOIN dbo.LL_users ON dbo.LL_activitys.Fk_UsrId = dbo.LL_users.PK_UsrId WHERE (MONTH(dbo.LL_activitys.ActivityDate) = '"+ IntMonthNo +"')")
Dim myConnection As SqlConnection
Dim mySqlAdapter As SqlDataAdapter
Dim myDataSet As DataSet
myConnection = New SqlConnection(strConn)
myConnection.Open()
mySqlAdapter = new SqlDataAdapter(strSQL,myConnection)
myDataSet = new DataSet()
mySqlAdapter.Fill(myDataSet,"Aktiviteter")
myDataView = New DataView
myDataView = myDataSet.Tables("Aktiviteter").DefaultView
myConnection.Close()
End Function
</script>
Altt fungerade ju tills jag slängde in If Not Page.IsPostBack then för att inte generera om dataviewn varje gång någon trycker på ett datum, eftersom inte min dataview är public så fungerar det inte nu.
Jag får
Exception Details: System.NullReferenceException: Object reference not set to an instance of an object
om jag klickar på ett datum eftersom jag inte når min instans av dataviewn, någon som känner sig manad att lära en nybörjare på asp.net och vb.net hur man skall gå tillväga.
NETworkMedlem sedan juni 20011 732 inlägg
erka skrev:
Har bytt till att visa datat för dagen i en DataList istället för en DataGrid, för att kunna formatera datan smidigt och exakt som jag vill.
Helt rätt, En datalist (eller en repeater) passar dina behov bättre om du vill göra den typen av formateringar som du har gjort (även om du kan använda templates i en datagrid också. Långsamt? Nejdå, visserligen snålar du inte på resurserna när du använder"latebound" men det är knappast någon fara när vi bara snackar om en enkel listning från en enkel databas. I jämförelse med gamnla asp är det fortfarande rena racern... :)
Däremot ska du inte använda en <a href=""> i din datalist utan en <asp:Hyperlink>. Inte för hastigheten utan för skalbarheten och dynamiken...
NETworkMedlem sedan juni 20011 732 inlägg Svar på ditt sista inlägg.
En smidig sak med asp.net som du kanske vet är att kontrollerna kan spara sina inställningar och värden över postbacks, du behöver inte sätta och hämta världen varje gång sidan laddas om. Detta sker med hjälp av viewstate, kod skickas med till klienten (den aspxsida som skickas till besökarens dator). När han elelr hon sedan gör en postback så skickas den här koden tillbaka till servern som använder den för att bygga upp kontrollerna igen så som de såg ut innan utan att du behöcver tänka på det.
Men om du fyller exempelvis ett dataset med data så fungerar lagringen annorlunda. Det finns ingen funktion som med automatik samlar på sig alla data som olika användare frågar efter och sparar dem till nästa gång de hämtar data från applikationen. Då måste du själv spara undan dessa data vilket kan göras på en rad olika sätt, exempelvis i en session eller att du skriver och läser från viewstate. Tänk dock på att det du då sparar i databashämtning förlorar du på att servern använder mer minne eller att viewstaten som skickas fram och tillbaka blir större.
Det är helt rätt tänk att försöka snabba upp en applikation. Men man måste väga nytta med nöje också. Vi pratar fortfarande om en ganska enkel applikation här där skillnaden i prestanda blir mätbar, inte märkbar. Jag tycker forfarande att du ska plocka ut rätt data redan i din sqlfråga istället för bolla med ett stort dataset över roundtrips, det är inte något problem att göra så här. :)
Sen om du vill göra på ditt sätt för att LÄRA dig, då är det en helt annan sak!
erkaMedlem sedan dec. 19996 522 inlägg Det är ju just för att lära mig och utnyttja nya saker som finns i asp.net som inte fanns med klassiska asp tekniken. Därför jag ställer så många korkade frågor he he. Nu har jag fått det att fungera, om du kollar igenom min kod snabbt så kanske du kan säga för och nackdelar och förklara varför, på det sättet som jag gjort.
Tack för all hjälp!
<script language="Vb" runat="server">
Public IntMonthNo as String
Public myDataSet AS DataSet
Public MyDataview AS Dataview
Public strConn As String = ConfigurationSettings.AppSettings("strConn")
Sub Page_Load
If Not Page.IsPostBack then
Dim CurrentDate as DateTime
CurrentDate = DateTime.Now()
IntMonthNo = CurrentDate.Month
GetEvents(IntMonthNo)
MyDataview.RowFilter = "ActivityDate = '" + LLCalendar.SelectedDate + "'"
LLCalenderList.DataSource = MyDataView
LLCalenderList.DataBind()
LLCalenderText.Text = CurrentDate.Date
End If
End Sub
Sub LLCalendar_OnSelectionChange(sender As Object, e As EventArgs)
MyDataview = Cache("CacheEvents")
MyDataview.RowFilter = "ActivityDate = '" + LLCalendar.SelectedDate + "'"
LLCalenderList.DataSource = MyDataView
LLCalenderList.DataBind()
LLCalenderText.Text = LLCalendar.SelectedDate
End Sub
Sub LLCalendar_VisibleMonthChanged(s as Object, e as MonthChangedEventArgs)
IntMonthNo = e.NewDate.Month
GetEvents(IntMonthNo)
End Sub
Sub LLCalendar_DayRender(o as object ,e as DayRenderEventArgs)
Dim d as CalendarDay = e.Day
Dim c as TableCell = e.Cell
If d.IsOtherMonth Then
c.Controls.Clear
End If
End Sub
Function GetEvents(IntMonthNo)
Dim strSQL As String = String.Format("SELECT dbo.LL_activitys.Pk_ActivityId, dbo.LL_activitys.Fk_UsrId, dbo.LL_activitys.ActivityDate, dbo.LL_activitys.ActivityHeader, dbo.LL_activitys.ActivityContent, dbo.LL_users.UsrFirstName , dbo.LL_users.UsrSurName FROM dbo.LL_activitys INNER JOIN dbo.LL_users ON dbo.LL_activitys.Fk_UsrId = dbo.LL_users.PK_UsrId WHERE (MONTH(dbo.LL_activitys.ActivityDate) = '"+ IntMonthNo +"')")
Dim myConnection As SqlConnection
Dim mySqlAdapter As SqlDataAdapter
Dim myDataSet As DataSet
myConnection = New SqlConnection(strConn)
myConnection.Open()
mySqlAdapter = new SqlDataAdapter(strSQL,myConnection)
myDataSet = new DataSet()
mySqlAdapter.Fill(myDataSet,"Aktiviteter")
myDataView = New DataView
myDataView = myDataSet.Tables("Aktiviteter").DefaultView
myConnection.Close()
Cache("CacheEvents") = myDataView
End Function
</script>
och i kalender kontrollen
OnDayRender = "LLCalendar_DayRender"
OnSelectionChanged = "LLCalendar_OnSelectionChange"
OnVisibleMonthChanged ="LLCalendar_VisibleMonthChanged"
NETworkMedlem sedan juni 20011 732 inlägg Ser bra ut, snyggt och rent. Inget att anmärka på, med en liten reservation för att jag inte kan just vb.net-syntaxen speciellt bra då. :) Sen när man blir varm i kläderna så kan man ju alltid "komprimera" koden lite hårdare, exempelvis;
myDataView = New DataView
myDataView = myDataSet.Tables("Aktiviteter").DefaultView
// samma som
myDataView = myDataSet.Tables("Aktiviteter").DefaultView
...men det är ju bara små detaljer. Då är du redo för nästa kliv då, codebehind och riktig objektorienterad programmering. :)
PaceMedlem sedan juni 20019 024 inlägg Lite off topic, men det passar ändå:
Sub Page_Load
Normalt sätt så anger man ju parametrarna "object" och "EventArgs". Är det verkligen alltid nödvändigt? Man behöver väl i stort sett aldrig skicka ett objekt "på" Page_Load, utan det är väl snarare så att man gör en ny subb/funktion för det ändamålet?!