webForumDet fria alternativet

Kalender kontroll

.NETur .NET

20 svar · 507 visningar · startad av erka

erkaMedlem sedan dec. 19996 522 inlägg
#1

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
#2

Kika i denna tråd: http://www.webforum.nu/showthread.php?s=&threadid=56193

erkaMedlem sedan dec. 19996 522 inlägg
#3

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
#4

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
#5

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
#6

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
#7

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
#8

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
#9

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
#10

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
#11

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
#12

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
#13

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
#14

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
#15

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
#16

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
#17

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
#18

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
#19

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
#20

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?!

151 ms totalt · 3 externa anrop · v20260731065814-full.29ac60f6
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
148 ms — hämta tråd, inlägg och bilagor (db)