Awesome Pull Request received? Merge it in!

So, you’re a developer or coordinator on a codeplex project. And while you where working on some brilliant new feature, another developer tumbled over a minor glitch in your code. Since he read my previous post on how to contribute to a codeplex project that’s on Git, he will fix the bug and send you a pull request.

But then what? Well, you will have to review what he’s done, and either accept or decline the pull request. Since Codeplex itself has some pretty decent document on Applying Pull Requests, I’ll just point you there.

You just go right ahead and read that, while I listen to some intermission.

Alright, good to have you back. So, when I go back to NB_Store on Codeplex, I’ll see what I got from my last post: An accpeted pullrequest:

image

When I accepted the pull request, codeplex already mentioned that I wasn’t done yet:

Note: Accepting this pull request will not merge the changes. You will need to do this manually by running the following commands locally:
1. Pull the changes into your local repository. We recommend that you create a new branch to test out the changes first.

2. If you’re satisfied, merge the changes and push them back to your repository on CodePlex.

  • git checkout master
  • git merge superska/nbstore
  • git push origin master

But, to be honoust, I’m not really into those git command line things. So, let’s see what we need to do with TortoiseGit.

Switching to the master

To be able to merge my changes in, I need to make sure I’m merging the changes in the right version of the code. So now, I need to forget about the origin repository for a while and make sure I’m working the master branch of NB_Store itself.

Please note that normally, the person sending the Pull request, will probably not be same one merging the changes in. But it doesn’t really matter from which repository you are switching. It just matters that you’re switch to the right one.

Since I was working on a fork of NB_Store, the assumption is, I can’t work directly on NB_Store. Which makes sense, because if I could, I wouldn’t need to fork it. Unless of course, I’m writing a blogpost about that process and… oh well, you get the point. So what I need to do now to get my working folder linked to the master branch of NB_Store itself, is of course clone it in 3 simp[le steps.

To be able to easily switch to using my fork again later on, I just renamed my original folder. Since all the Git information is stored inside it, this works brilliantly. I’ll just rename it back later on. To clone the NB_Store master branch…

One:

image

Two:

image

Three:

image

Wait a bit ‘till everything’s downloaded and we’re done.

Pulling in the changes

Next task is to pull in the changes this “superska” guy sent me in his pull request. Since CodePlez already allowed me to view the changes in the pull request, I’m perfectly fine pulling them right in the master branch.

image

If I wasn’t, I’d just create a feature branch for it, pull the changes there, test them and later on, merge that branch back into master.

But now, I use TortoiseGit—> Pull to pull in the changes from the request:

image

The status window gives me a button “Pulled Diff” to review the changes once again. Now I should test the code and make sure I want to

Merge that new stuff in!

To merge the new code into the NB_Store master branch, I need to chackout that master branch again first: TortoiseGit, Switch/Checkout, chose branch “remotes/origin/master”.

To merge the changes in, chose TortoiseGit, Merge. Select the Commit radio button in the dialog.:

image

The only way I found to get a hold on that changeset SHA-1 key, is to go to NB_Store on codeplex, go to Source Code, Pull Requests, and take it from the URL here:

2014-04-30_08-51-35_2014-04-29_23-40-43_NB_Store - Free DotNetNuke Ecommerce Catalog Module - Source

The master demands commitment

The merge is already committed to my local repository, so I didn’t see the red icons I expected at first. Since it’s committed locally, I need to push it to origin/master (because I’m working on the NB_Store project now, and not on a fork, origin is now nb_store/master):

image

And since the proof of the pudding is always in the eating:

image

Hope this helps understanding (and working with) git a bit. I know it helped me to figure things out.

Contributing to a CodePlex Project that’s on Git

Using Git is one of those things I’ve been postponing for ages. At 40Fingers (and pretty much all other projects I’m involved in) we’re using SVN as our versioning system. I know how it works, it does what I need it to do, so why bother? Well, because everybody around me seems to be leaving SVN for Git and they can’t ALL be wrong, right?

Anyway, there’s probably plenty of other content out there about why you should or shouldn’t use either one. I decided I need to, se here goes…

Since I’m one of the devlopers for NB_Store, which is an open source e-commerce module for DotNetNuke, I fixed a bug in it. While I could of course commit the fix straight into the main development branch (or the master for that matter), for this blogpost, I’ll do it using a pull request.

Step 0: install TortoiseGit

Since I haven’t done much with Git at all, I don’t know much about what Git client would be the best. I’m pretty happy with TortoiseSVN, so I figured I’d give TortoiseGit a shot. Get it here: http://code.google.com/p/tortoisegit/

Step 1: Create a fork

So, what do we need a fork for? Well, It allows me to  have my own copy of the NB_Store sources on Codeplex. I can keep it in Sync with the official project, create my own branches for development and send pull requests to the main project when I’m happy with something.

So, off we go, to then NB_Store project on CodePlex, log in and navigate straight to the Source Code tab. Things might look a little difference at your end, because I happen to be a coordinator on the project:

https://nbstore.codeplex.com/SourceControl/latest

image

I’m going to fork the current master branch. So I have “master” selected and click the Fork link and click “Create new fork” in the popup panel:

image

Since this will be my own nb_store development fork, not for one specific feature, I’ll just name it “nbstore”

and click Save on the form that appears:

image

Now, you see there’s an extra fork on the NB_Store master branch:

image

Step 2: Clone the fork

The fork as “in the cloud” on CodePlex. I can’t work on that, I need to have the code locally on my machine, of course.

So, to create my clone, I’m going to open DNN’s DesktopModules folder in Windows Explorer, right click and choose “Git Clone…”:

image

I’m creating a clone right from my CodePlex fork into my working folder:

image

Clicking OK initiates the Download of all files to my pc.

At this point, there are 3 repositories of NB_Store I’m working with:

  1. the upstream repository: the main NB_Store repository on CodePlex
  2. the origin reopsitory: my own fork of NB_Store, also on CodePlex
  3. the local repository in the DesktopModules folder on my own machine

Step 3: Branch

Now, while I could open the project now and start working, it’s advisable to create a so-called feature branch first. That will keep my fork nice and clean over time. It will also make it a lot easier to create single-feature pull requests.

I need to fix an issue related to all-lowercase-url’s for NB_Store’s backoffice module. If you’re not all that familiar with NB_Store: forget it. I just mean I need to make a feature-branch and name it something that makes sense. So, right-click my local repository folder, select TortoiseGit submenu and select Create Branch:

image

Notice that I’m switching to the new branch right away.

Step 4: Make that change

I’m not going to cover that here: I’m making the change I need to make in the code. In this case it’s only a few lines in a single file.

Step 5: Commit the change

Now that I’ve made my change, I’ll need to get it stored on CodePlex. To get that done, I use the TortoiseGit context menu again and choose the quick Git Commit option:

image

Next, I’ll enter a commit message and click OK. The next dialog allow me to push my changes to my origin right away:

image

I will need to enter the remote branch name here too, and click OK. You might be asked for your CodePlex credentials at this point:

image

Now, when I go back to NB_Store on CodePlex and select my fork, I will see my own feature branch in the dropdown, and when I select it, I’ll see my commit:

image

Step 6: Create a Pull Request

Finally, I want to send my changes to the development team to allow them to review it and merge the changes in some release if they choose to. This is all done on CodePlex itself. Click the link “Send pull request” in the above screenshot:

image

Make sure you’re sending a pull request from the right branch (I chose my new feature branch and the upstream master). Then fill out the little form with some handy information and click send:

image

 

I know this helped me understand Git a bit better, so if you want to give it a shot yourself, just go ahead and give it try!

DotNetNuke 6 en Internet Explorer 10

Een veel gehoord probleem met DotNetNuke 6 websites, is de laatste tijd: “ik kan niet inloggen in Internet Explorer 10!”


Doordat Windows 8 met Internet Explorer 10 (IE10) wordt geleverd, en DotNetNuke 6 websites voorlopig nog lang niet allemaal geüpgraded zijn naar DotNetNuke 7, zal dit punt de komende tijd alleen maar vervelender gaan worden.


Sommige gebruikers (en beheerders) hebben al ontdekt dat het niet alleen inloggen is dat niet werkt, maar bijna alle “postback” acties. En wellicht zelfs dat het probleem opgelost (“omzeild” is wellicht een beter woord) kan worden door de browser in compatibiliteitsmodus te zetten.


image
De compatibiliteits-modus knop in IE10


Maar dat is natuurlijk niet echt een oplossing: je wilt immers geen melding op je site zetten die overkomt als:


“Onze website is hopeloos verouderd, dus om hem te kunnen gebruiken, moet je eerst dat rare knopje rechts bovenin aanklikken”


Gelukkig kan een website ook zélf tegen IE10 zeggen dat de site in compatibiliteitsmodus weergegeven moet worden. En met behulp het immer onvolprezen StyleHelper SkinObject van mijn collega Timo Breumelhof, kan dat gewoon in de skin worden geregeld.


Hoe doe je dat?


1. Download de laatste versie van het StyleHelper SkinObject en installeer het op je website (zoals je iedere module zou installeren)


2. Open je skin .ascx bestand in een editor en registreer het skinobject met de regel:


<%@ Register TagPrefix=”fortyfingers” TagName=”STYLEHELPER” Src=”~/DesktopModules/40Fingers/SkinObjects/StyleHelper/StyleHelper.ascx” %>


3. Gebruik vervolgens het skinobject om de meta-tag toe te voegen die IE10 de compatibiliteitsmodus instructie geeft:


<fortyfingers:STYLEHELPER ID=”STYLEHELPER1″ AddToHead=’<meta http-equiv=”x-ua-compatible” content=”IE=9″ />AddAtEnd=”False” runat=”server” />


Let op: AddAtEnd moet False zijn, anders komt de meta-tag ná de javascripts in de pagina, en dan werkt het niet.


Correct toegepast functioneert de site weer naar behoren en is de compatibiliteitsmodus-knop niet meer zichtbaar.


Visual Studio LightSwitch in de praktijk–Deel 7–Een detailscherm uitbreiden met gerelateerde informatie

Note: since there’s quite a lot of content on Visual Studio LightSwitch available in English on the web already, I decided to publish this series in Dutch.

Begin 2011 heeft Microsoft de eerste beta van VS LightSwitch met Go-Live licentie gelanceerd, een nieuw product in de Visual Studio familie, waarmee razendsnel zowel web- als desktop SilverLight "Line of Business" applicaties kunnen worden gemaakt. Hoewel de doelgroep van VS LightSwitch niet primair bestaat uit hard-core .net developers, zal het ook voor deze groep zeker waardevol kunnen zijn om de mogelijkheden en beperkingen van LightSwitch te leren kennen.

In de aanloop naar DevDays11 ben ik begonnen met een serie blogs over dit onderwerp. De eerste post was het inleidende artikel. De volgende artikelen zijn/worden:

Inleiding

Tot nu toe heb ik in deze serie alleen schermen gebruikt met gegevens van 1 entiteit daarop. Vanzelfsprekend is dat niet het enige soort scherm waarmee ik in mijn applicatie te maken heb en gelukkig heeft het Visual Studio LightSwitch team ook hierin voorzien.

In mijn applicatie wil ik op het detailscherm van een student, zowel zijn Afspraken en DoorlopendeAfspraken laten zien. Ik kies weer voor Add New Screen in het contextmenu van de Solution Explorer. Ik kies voor “Details Screen” en "de Student entiteit. Tevens vink ik nu de vakjes van de gerelateerde informatie aan:

image
Figuur 1: Een detailscherm met gerelateerde informatie maken

Zonder ook maar iets aangepast te hebben, ziet het scherm er nu al zo uit:

image
Figuur 2: Het gegeneerde scherm met gerelateerde gegevens

Zoals met alles in LightSwitch, is het weer heel doorzichtig hoe dit is gedaan, zodat ik ook later nog extra informatie zou kunnen toevoegen aan het scherm, zonder via de wizard een nieuw scherm te maken. (Merk op dat onderstaand screenshot later is gemaakt en er inmiddels meer functionaiteit aan het scherm is toegevoegd):

image
Figuur 3: Het scherm in de screen designer

Allereerst zijn de gegevenssets aan het ViewModel-deel van de designer (links) toegevoegd. Daarnaast is een Tab Layout control aan de Control Tree (midden) toegevoegd. Tenslotte is voor ieder van de gegevenssets een datagrid toegevoegd. De databinding aan het grid werkt vervolgens wee hetzelfde als we eerder hebben gezien bij een zoekscherm.

Middels de knop “Add Data Item” kan handmatig hetzelfde worden bereikt met een al bestaand scherm:

image
Figuur 4: Handmatig een gegevensset aan een scherm toevoegen

Vervolgens kan met (onder andere) de knop ernaast een element aan het scherm worden toegevoegd, dat aan de nieuwe gegevensset gekoppeld kan worden. Zo wordt eenvoudig exact hetzelfde resultaat bereikt als via de wizard. En dat moet ook, anders ben je in de aap gelogeerd als je aan een eerder gemaakte applicatie, functionaiteit wilt toevoegen.

Visual Studio LightSwitch in de praktijk–Deel 6–Logica toevoegen aan een entiteit

Note: since there’s quite a lot of content on Visual Studio LightSwitch available in English on the web already, I decided to publish this series in Dutch.

Begin 2011 heeft Microsoft de eerste beta van VS LightSwitch met Go-Live licentie gelanceerd, een nieuw product in de Visual Studio familie, waarmee razendsnel zowel web- als desktop SilverLight "Line of Business" applicaties kunnen worden gemaakt. Hoewel de doelgroep van VS LightSwitch niet primair bestaat uit hard-core .net developers, zal het ook voor deze groep zeker waardevol kunnen zijn om de mogelijkheden en beperkingen van LightSwitch te leren kennen.

In de aanloop naar DevDays11 ben ik begonnen met een serie blogs over dit onderwerp. De eerste post was het inleidende artikel. De volgende artikelen zijn/worden:

Inleiding

Eén van de belangrijke functionaliteiten van de applicatie die ik in deze serie artikelen aan het maken ben, is het eenvoudig kunnen maken van een doorlopende afspraak. De use case is op zich niet moeilijk:

Een docent moet eenvoudig kunnen registreren dat met een student is afgesproken dat deze van datum A tot datum B, op bepaalde momenten in de week voor ondersteuning langs komt. In het overzicht afspraken moeten de studenten die ten gevolge van een dergelijke afspraak worden verwacht, ook te zien zijn, en moet kunnen worden geregistreerd of zij daadwerkelijk zijn gekomen.

Hoewel er – zoals zo vaak in software ontwikkeling – natuurlijk meer wegen zijn die naar Rome leiden, heb ik er hier voor gekozen om bij het bewaren van een DoorlopendeAfspraak te zorgen dat individuele afspraken worden aangemaakt, die aan de DoorlopendeAfspraak gekoppeld zijn. Dat houdt natuurlijk ook in dat, indien de DoorlopendeAfspraak gewijzigd wordt, de bijbehorende afspraken die vòòr vandaag liggen, ook moeten worden aangepast.

Bij een DoorlopendeAfspraak wordt voor iedere dag van de week (maandag t/m vrijdag) vastgelegd of de student op die dat dient de komen (middels een boolean veld) en zo ja, om hoe laat (string). Vooral voor wat betreft het tijd-veld zijn natuurlijk andere keuzes mogelijk, maar omdat ik hier met een bestaand datamodel te maken heb, kies ik nu hiervoor.

Om te beginnen pas ik de visual tree wat aan om het scherm handiger te laten werken en vooral wat minder langerekt te zijn. Dit scherm telt immers veel, kleine velden:

image
Figuur 1: Aanpassingen aan de visual tree voor een handiger schermlayout

De UI is hiermee wat mij betreft klaar. Alles wat ik nu nog moet doen, is het toevoegen van de juiste logica om:

  1. de tijdvelden alleen-lezen te maken wanneer de bijbehorende CheckBox niet is aangevinkt
  2. de tijdvelden te valideren
  3. alle Afspraken te maken wanneer de DoorlopendeAfspraak wordt opgeslagen

Voor al deze aanpassingen moet ik dus NIET in de Screen Designer zijn, maar in de DataModel Designer. Het is hier namelijk geen logica van het scherm waar we het over hebben, maar van het model. Ik dubbelklik in de Solution Explorer dus op de entiteit DoorlopendeAfspraken om op de juiste plaats in de DataModel Designer te komen.

Wie het eerst komt, die het eerst maalt, dus ik begin bij puntje 1. Hiervoor selecteer ik het veld “MaandagTijd” en klik rechts boven in het scherm het menu Write Code open. Je ziet dat er een behoorlijke hoeveelheid methodes is, waarop ik met code kan inhaken. Bovenaan staan gelukkig de methoden die van toepassing zijn op de geselecteerde eigenschap. Ik heb hier dus de _IsReadOnly methode nodig:

image
Figuur 2: De vele methoden om op in te haken bij een entiteit

Vervolgens kom ik in een code editor tik ik de bijzonder eenvoudige regel code die ervoor zorgt dat het veld op het juist emoment niet meer wijzigbaar is:

   1:  public partial class DoorlopendeAfspraak
   2:  {
   3:      partial void MaandagTijd_IsReadOnly(ref bool result)
   4:      {
   5:          result = !Maandag;
   6:      }
   7:  }






.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Listing 1: Zorgen dat een veld “alleen lezen” wordt



Natuurlijk kopieer ik dit voor de velden van de andere dagen.



De validatie (punt 2) werkt op dezelfde manier:



   1:  partial void MaandagTijd_Validate(EntityValidationResultsBuilder results)
   2:  {
   3:      TimeSpan time;
   4:      if (!TimeSpan.TryParseExact(MaandagTijd, "H:mm", System.Globalization.CultureInfo.CurrentCulture, out time))
   5:      {
   6:          results.AddPropertyError("Tijd bij maandag is incorrect.");
   7:      }
   8:  }






.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Listing 2: Validatie voor een veld toevoegen



En tenslotte punt 3: het toevoegen van logica waarmee alle afspraken die voortvloeien uit de DoorlopendeAfspraak, worden toegevoegd in de database. Op dezelfde plaats als hiervoor in Figuur 2, klik ik op DoorlopendeAfspraken_Inserting. Het EntityObject dat ik hier aan het toevoegen ben, krijg ik als parameter mee in de methode. Deze gebruik ik dan ook bij het manipuleren van de data:



   1:  partial void DoorlopendeAfspraken_Inserting(DoorlopendeAfspraak entity)
   2:  {
   3:      // hier alle afspraken maken zolang de doorlopendaAfspraak loopt
   4:      var t = entity.BeginDatum;
   5:      if (t < DateTime.Today) t = DateTime.Today;
   6:   
   7:      while (t <= entity.EindDatum)
   8:      {
   9:          switch (t.DayOfWeek)
  10:          {
  11:              case DayOfWeek.Monday:
  12:                  if (entity.Maandag)
  13:                  {
  14:                      var a = entity.Afspraken.AddNew();
  15:                      a.DatumTijd = t.Date.Add(ParseTijd(entity.MaandagTijd));
  16:   
  17:                      a.Locatie = entity.Locatie;
  18:                      a.Student = entity.Student;
  19:                  }
  20:                  break;
  21:              default:
  22:                  break;
  23:          }
  24:          t = t.AddDays(1);
  25:      }
  26:  }






.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Listing 3: Logica om Afpsraken te maken bij het toevoegen van een doorlopende afspraak



Ik heb omwille van de duidelijkheid de meeste dagen weggelaten. Het gaat om het principe en dat lijkt me duidelijk zo. Merk op dat ik hier dus niet zelf hoef te zorgen voor het daadwerkelijk opslaan in de database. Ik pas alleen het model aan, LightSwitch zorgt dat de wijzigingen uit het model in de Database terecht komen.



Zoals je eerder al zag, is er een groot aantal methodes waarvoor je code kunt schrijven. Dit maakt een LightSwitch applicatie bijzonder flexibel en aanpasbaar. De voorbeelden die ik hier gebruikt heb, zijn slechts enkele van de mogelijkheden.

Visual Studio LightSwitch in de praktijk–Deel 5–Een invoerscherm customizen

Note: since there’s quite a lot of content on Visual Studio LightSwitch available in English on the web already, I decided to publish this series in Dutch.

Begin 2011 heeft Microsoft de eerste beta van VS LightSwitch met Go-Live licentie gelanceerd, een nieuw product in de Visual Studio familie, waarmee razendsnel zowel web- als desktop SilverLight "Line of Business" applicaties kunnen worden gemaakt. Hoewel de doelgroep van VS LightSwitch niet primair bestaat uit hard-core .net developers, zal het ook voor deze groep zeker waardevol kunnen zijn om de mogelijkheden en beperkingen van LightSwitch te leren kennen.

In de aanloop naar DevDays11 ben ik begonnen met een serie blogs over dit onderwerp. De eerste post was het inleidende artikel. De volgende artikelen zijn/worden:

Inleiding

Natuurlijk moeten in mijn applicatie ook nieuwe afspraken ingevoerd kunnen worden. Hiervoor voeg ik via de Solution Explorer een nieuw scherm toe, en kies voor het type “New Data Screen”:

image
Figuur 1: Aanmaken van een nieuwe scherm voor afspraken

LightSwitch maakt vervolgens een invoerscherm voor afspraken aan, wat al bijzonder dicht in de buurt komt van wat ik nodig heb. Ik heb voldoende aan de visual tree om te zien wat ik nog moet wijzigen. En dat is niet eens veel:

image
Figuur 2: Invoerscherm voor Afpsraak, zoals LightSwitch dat genereert

Het Id veld is al netjes een niet wijzigbaar veld geworden, een boolean veld is een CheckBox en de Foreign Key relaties hebben een Auto Complete Box gekregen. Het is slechts een kwestie van minuten om dit scherm precies te maken zoals ik het wil hebben:

  1. Id verwijderen
  2. Doorlopende Afspraak verwijderen (die entiteit heeft een andere functie en komt terug in een later artikel)
  3. Het vel “Aanwezig” moet standaard aan komen te staan (aangezien het scherm normaal gebruikt wordt voor registratie wanneer een student onaangekondigd langs komt)
  4. Student moet een popup-scherm worden (want er zijn duizenden studenten in de applicatie)
  5. De volgorde moet voor de gebruiker iets logischer worden

Puntjes 1 en 2 zijn natuurlijk bijzonder eenvoudig: de velden kunnen eenvoudigweg uit de tree worden verwijderd. Ik kan ook de Visible property hiervan uitschakelen, maar ik ga me niet bedenken: ze kunnen weg.

In het vorige artikel heb ik al laten zien hoe een standaardwaarde op een zoekscherm in code te beïnvloeden is. Voor andere schermtypes is dat niet anders. Via Write Code kan ik de methode CreateNewAfspraak_InitializeDataWorkspace aanpassen. Ik heb hier alleen regel 7 toegevoegd:

   1:  public partial class CreateNewAfspraak
   2:  {
   3:      partial void CreateNewAfspraak_InitializeDataWorkspace(List<IDataService> saveChangesTo)
   4:      {
   5:          // Write your code here.
   6:          this.AfspraakProperty = new Afspraak();
   7:          this.AfspraakProperty.IsAanwezig = true;
   8:      }
   9:   
  10:      partial void CreateNewAfspraak_Saved()
  11:      {
  12:          // Write your code here.
  13:          this.Close(false);
  14:          Application.Current.ShowDefaultScreen(this.AfspraakProperty);
  15:      }
  16:  }







.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Listing 1: Eenvoudige code om de standaardwaarde van een veld aan te passen



Punt 4, de Auto Complete box veranderen in een zoekschermpje, lijkt wellicht wat lastiger, maar wederom maakt LightSwitch er een eenvoudige taak van: ik kan het type “Auto Complete Box” veranderen in “Modal Window Picker” en ik ben eigenlijk alweer klaar. LightSwitch maakt dan een zoekscherm op basis van de Summary Property van de Student entiteit, dat kan ik wel aanpassen, maar daaraan heb ik nu geen behoefte.



De volgorde (punt 5) is ook niet zo moeilijk aan te passen, dus kan ik even kijken wat er nu van het scherm geworden is:



image


Figuur 3: Het supersnel gemaakte invoerscherm is behoorlijk goed



Gebruik je dit scherm om een nieuwe afspraak in te voeren, dan opent na het opslaan een standaard gegenereerd detailscherm voor de afspraak. Omdat dat natuurlijk weer net niet precies is wat ik nodig heb, voeg ik ook gelijk een detailscherm voor Afsrpaak toe. Bij het aanmaken geef ik direct aan dat dit het standaardscherm voor Afspraak gaat worden:



image


Firguur 4: Nieuw detailscherm toevoegen als standaardscherm voor een entiteit



Het detailscherm komt er verder nagenoeg hetzelfde uit te zien als het invoerscherm. Het enige dat ik hier graag wil toevoegen, is een indicatie dat de afspraak hoort bij een doorlopende afspraak. Hiervoor klik ik bovenin de Screen Designer op “Add Data Item” en specificeer mijn nieuwe data item. Ik voeg nu dus een element toe aan de ViewModel, het linker deel van de Screen Designer:



image


Figuur 5: Data element toevoegen aan een scherm



Vervolgens kan ik in code een regel toevoegen aan de methode AfspraakDetail_Created, om mijn nieuwe property de juiste waarde te geven:



   1:  partial void AfspraakDetail_Created()
   2:  {
   3:      // Write your code here.
   4:      IsDoorlopendeAfspraak = Afspraak.DoorlopendeAfspraak != null;
   5:  }


Listing 2: Toegevoegde property een waarde geven in code





.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }



Omdat ik het element wel als een checkbox op het scherm wil hebben, maar toch niet wil dat het gewijzigd wordt,



pas ik nog even een simpel trucje toe in de IsDoorlopendeAfspraak_Changed methode:



   1:  partial void IsDoorlopendeAfspraak_Changed()
   2:  {
   3:      // We're just setting it back to it's original value
   4:      if (IsDoorlopendeAfspraak != (Afspraak.DoorlopendeAfspraak != null))
   5:      {
   6:          IsDoorlopendeAfspraak = Afspraak.DoorlopendeAfspraak != null;
   7:      }
   8:  }







.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Listing 3: IsDoorlopendeAfspraak terugzetten als het veld gewijzigd wordt. Poor man’s readonly…

Visual Studio LightSwitch in de praktijk–Deel 4–Parameters toevoegen aan een scherm

Note: since there’s quite a lot of content on Visual Studio LightSwitch available in English on the web already, I decided to publish this series in Dutch.

Begin 2011 heeft Microsoft de eerste beta van VS LightSwitch met Go-Live licentie gelanceerd, een nieuw product in de Visual Studio familie, waarmee razendsnel zowel web- als desktop SilverLight "Line of Business" applicaties kunnen worden gemaakt. Hoewel de doelgroep van VS LightSwitch niet primair bestaat uit hard-core .net developers, zal het ook voor deze groep zeker waardevol kunnen zijn om de mogelijkheden en beperkingen van LightSwitch te leren kennen.

In de aanloop naar DevDays11 begin ik met een serie blogs over dit onderwerp. De eerste post was het inleidende artikel. De volgende artikelen zijn/worden:

Inleiding

In dit deel van de serie, ga ik het afspraken scherm uit het vorige deel nog en stap verder uitbouwen. De gebruiker is namelijk neit geïnteresseerd in een scherm waar alle afspraken op staan, maar een scherm waar alle afspraken van een dag op staan. Bij het opnen van dat scherm, moeten dat natuurlijk de afspraken van “vandaag” zijn.

Om dit te kunnen realiseren, moeten we de query die aan het scherm ten grondslag ligt, kunen parametriseren. Het goede nieuws is dan gelukkig weer, dat LightSwitch hierin voorziet. Er zijn zelfs verschillende mogelijkheden om dit te doen. Eén mogelijkheid is, om in de Screen Designer van SearchAfspraken voor “Edit Query” (in het linker deel van het scherm (het ViewModel-deel)) te kiezen:

image
Figuur 1: Edit Query Link

Een parameter “DateParameter” toe te voegen:

image 
Figuur 2: Parameter toevoegen aan de query van een scherm

En de data op deze nieuwe parameter te filteren:

image
Figuur 3: Filtermogelijkheden staan niet toe een DateTime veld te filteren op Date

Lastigheidje is hier, dat ik de entiteit Afspraak alleen een veld DatumTijd van het type DateTime heb gegeven. De standaard filtermogelijkheden, geven me wel de mogelijkheid om te filteren op een parameter, maar staan niet toe op de parameter eerst een methode (Zoals DateParameter.Date() ) aan te roepen.

Back to the drawing board dus…

Gelukkig biedt LightSwitch diverse mogelijkheden om dit probleem toch op te lossen.

Ik zou bijvoorbeeld een custom veld “Datum” van het type Date kunnen toevoegen aan de entiteit Afspraak en dit veld de waarde geven van het datum-deel van het “DatumTijd” veld. Vervolgens kan ik een filter toevoegen dat het nieuwe veld “Datum” vergelijkt met mijn DateParameter. Gevolg is dan wel, dat bij het openen van het scherm, alle Afspraken moeten worden opgehaald om het Datum-veld te berekenen en te zien of het voldoet aan mijn filter.

Een andere – en in dit geval betere – oplossing is het om de DateParameter direct in de query te laten controleren. Het scherm Overzicht Afspraken is nu gebaseerd op een query die alle Afspraken retourneert. In plaats daarvan heb ik nu een geparametriseerde query nodig, die de afspraken van 1 dag retourneert. Hiervoor klik ik in de Solution Explorer in het contextmenu van de entiteit Afspraken op “Add Query”:

image
Figuur 4: Nieuwe query toevoegen voor een entiteit

De nieuwe query geef ik een handige naam (“AfsprakenByDate”) en voeg de DateParameter toe, zoals ik dat in het scherm ook al gedaan had. De volgende stap is dat ik zorg dat in de query de DatePArameter daadwerkelijk gecontroleerd wordt.

image
Figuur 5: Een eigen query, met eigen parameters

In het dropdown-lijstje “Write Code” kan ik kiezen voor de methode “<querynaam>_PreProcessQuery”. Als ik dat doe krijg ik de mogelijkheid om de query van het scherm aan te passen, voordat hij wordt uitgevoerd. De DateParameter die ik aan de query had toegevoegd, krijg ik hier als parameter in de methode tot mijn beschikking. In mijn geval voek ik een paar regels code toe om te zorgen dat de controle op het DatumTijd veld correct wordt uitgevoerd:

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Text;
   5:  using Microsoft.LightSwitch;
   6:  using Microsoft.LightSwitch.Security.Server;
   7:  namespace LightSwitchApplication
   8:  {
   9:      public partial class SterDataService
  10:      {
  11:          partial void AfsprakenByDate_PreprocessQuery(DateTime? DateParameter, ref IQueryable<Afspraak> query)
  12:          {
  13:              var minDate = DateParameter.GetValueOrDefault();
  14:              var maxDate = DateParameter.GetValueOrDefault().AddDays(1).AddSeconds(-1);
  15:              query = from a in query
  16:                      where a.DatumTijd >= minDate && a.DatumTijd <= maxDate
  17:                      select a;
  18:          }
  19:      }
  20:  }

Listing 1:  Code om de query te laten werken met mijn parameter



Nu ik de query gemaakt heb om de Afspraken per dag op te halen, moet ik het overzicht afspraken nog aanpassen om deze query te gaan gebruiken. In de Properties van de Screen Designer kan ik hiervoor de Query Source aanpassen (bij de rode pijl). In de groene elips zie je dat LightSwitch zelf de DateParameter aan het scherm heeft toegevoegd.



image


Figuur 6: Het scherm met de aangepaste query



Overigens zijn alle elementen in het ViewModel deel van de Screen Designer aangepast aan het resultaat van mijn query, maar omdat hieraan verder niets gewijzigd is, zie je dat hier niet terug.



Volgende stap is het toevoegen van een datumveld op het scherm, waar de gebruiker de datum kan selecteren. We voegen dus in de View een control toe, dat via databinding gekoppeld is aan de property DateParameter van de ViewModel. Of liever gezegd, dat laten we LightSwitch doen:



image


Figuur 7: Schermelement toevoegen voor de invoer van een parameter



Ik verplaats het toegevoegde veld vervolgens naar boven, omdat ik het graag bovenin het scherm wil hebben en pas de property “Display Name” aan. Wat nu nog rest, is dit veld bij het openenen van het scherm de datum van vandaag te geven. Hiervoor schrijf ik een paar regels code in de methode InitializeDataWorkspace van het scherm:



image
Figuur 8: Ook bij een scherm kun je eigen code invoegen



Geheel volgens MVVM geef ik dus de property DateParameter van de ViewModel een waarde:



   1:  public partial class SearchAfspraken
   2:  {
   3:      partial void SearchAfspraken_InitializeDataWorkspace(List<IDataService> saveChangesTo)
   4:      {
   5:          // Write your code here.
   6:          AfspraakDateParameter = DateTime.Today;
   7:      }
   8:  }


Listing 2: Parameterveld van een standaardwaarde voorzien



Het resultaat is nu dat er een parameterveld op het scherm staat, dat standaard de datum van dandaag als waarde heeft. De getoonde data is altijd gefilterd op de waarde van die parameter:



image
Figuur 9: Het aangepaste scherm met datumparameterveld.

Visual Studio LightSwitch in de praktijk–Deel 3–Schermelementen aanpassen

Note: since there’s quite a lot of content on Visual Studio LightSwitch available in English on the web already, I decided to publish this series in Dutch.

Begin 2011 heeft Microsoft de eerste beta van VS LightSwitch met Go-Live licentie gelanceerd, een nieuw product in de Visual Studio familie, waarmee razendsnel zowel web- als desktop SilverLight "Line of Business" applicaties kunnen worden gemaakt. Hoewel de doelgroep van VS LightSwitch niet primair bestaat uit hard-core .net developers, zal het ook voor deze groep zeker waardevol kunnen zijn om de mogelijkheden en beperkingen van LightSwitch te leren kennen.

In de aanloop naar DevDays11 begin ik met een serie blogs over dit onderwerp. De eerste post was het inleidende artikel. De volgende artikelen zijn/worden:

Inleiding

In het vorige artikel in deze serie, heb ik een min-of-meer standaard zoekscherm gemaakt. Dat scherm voldoet al aardig op die manier. Het volgende scherm dat ik nodig heb, is een overzicht afspraken per dag. Het doel van dit overzicht is niet alleen inzicht te hebben in de afspraken die op een dag plaatsvinden, maar (o.a.) ook om snel te kunnen aanvinken als een student zich meldt.

Omda dit overzichtsscherm in de basis wel heel veel weg heeft van een zoeksherm heb ik, net als voor het vorige scherm, weer voor de search layout gekozen. Verder heb ik slechts enkele velden verwijderd uit de standaard layout. In de designer en runtime ziet het scherm er nu alsvolgt uit:

image image
Figuur 1: De screen designer van het scherm Overzicht afspraken
Figuur 2: Het scherm Overzicht afspraken in debug modus

Nu is er een aantal wijzigingen dat ik wil toepassen op het scherm:

  1. De kolom Datum Tijd moet “Afspraak” gaan heten
  2. Datum Tijd moet Nederlands geformatteerd worden
  3. De kolom Aanwezig moet een wijzigbare CheckBox worden
  4. De kolom docent moet een wijzigbare DropDown lijst met docenten worden

Kolom Datum Tijd hernoemen

Hiervoor ga ik weer naar de entiteit Afspraken en wijzig de property “Display Name” van het veld DatumTijd, omdat ik overal in de applicatie wil dat dit veld wordt aangeduid met “Afspraak”.

Datum Tijd Nederlands opmaken

Dit is een makkelijke. Bij de eigenschappen van de applicatie kan ik op het tabje General Properties, eenvoudigweg de Culture aanpassen:

image 
Figuur 3: Culture van de applicatie wijzigen

Wijzigbare checkbox maken van Boolean veld

Zoals je in de Screen Designer kunt zien, wordt het veld “IsAanwezig” (waarvan ik de Display Name trouwen ook nog even moet aanpassen) wergegeven in een Label Control:

image
Figuur 4: In de screendesigner ligt vast welk control wordt gebruikt voor een veld.

Door op het driehoekje naast “Label” te klikken, kan ik dit control wijzigen in CheckBox:

image
Figuur 5: Type control wijzigen is erg eenvoudig

Dropdown lijst maken van Foreign Key relaties

Op dezelfde manier als hiervoor met de CheckBox, maak ik van de kolom “Docent” een Auto Complete Box.

Na deze wijzigingen ziet het scherm er alsvolgt uit:

image
Figuur 6: De laatste 3 kolommen zijn nu wijzigbaar.

Visual Studio LightSwitch in de praktijk–Deel 2–Een zoekscherm maken

Note: since there’s quite a lot of content on Visual Studio LightSwitch available in English on the web already, I decided to publish this series in Dutch.

Begin 2011 heeft Microsoft de eerste beta van VS LightSwitch met Go-Live licentie gelanceerd, een nieuw product in de Visual Studio familie, waarmee razendsnel zowel web- als desktop SilverLight "Line of Business" applicaties kunnen worden gemaakt. Hoewel de doelgroep van VS LightSwitch niet primair bestaat uit hard-core .net developers, zal het ook voor deze groep zeker waardevol kunnen zijn om de mogelijkheden en beperkingen van LightSwitch te leren kennen.

In de aanloop naar DevDays11 ben ik begonen met een serie blogs over dit onderwerp. De eerste post was het inleidende artikel. De volgende artikelen zijn/worden:

Scherm toevoegen

In het vorige artikel in deze serie heb ik de Data Source (mijn SQLServer database) aan het LightSwitch project gekoppeld. In dit artikel gaan we aan de slag met het maken van schermen in de LightSwitch applicatie.

Een scherm toevoegen aan je VSLS applicatie doe je weer vanuit het contextmenu in de Solution Explorer:

image
Figuur 1: Scherm toevoegen via Add Screen

Voordat het scherm wordt toegevoegd, moet ik een keuze maken uit de verschillende typen schermen die VSLS kent. Standaard zijn er 5 schermtypen. Omdat ik graag wil beginnen met het zoekscherm voor studenten, kies ik voor Search Data Screen:

image
Figuur 2: Ik begin met het maken van een zoekscherm voor studenten

Screen Designer

Na het toevoegen opent de LightSwitch Designer (die je dus ook gebruikt voor de Data Source / Entiteiten) zich, met het nieuwe scherm:

image
Figuur 3: De VSLS Designer in Scherm modus

De schermdesigner in Vsual Studio LightSwitch verdient een beetje extra aandacht. Wat hieraan opvalt, hangt natuurlijk een beetje af van wat je gewend bent. De kans is groot dat je hier iets visueels had verwacht met schermelementen die je kunt plaatsen en verplaatsen. In VSLS echter, ligt de schermlayout vast in het schermtype dat je eerder hebt gekozen. In deze designer wordt je er eigenlijk mee geconfronteerd dat VSLS helemaal volgens het Model-View-ViewModel (MVVM) pattern is opgezet. Dat is interessant om te weten voor degenen die ermee bekend zijn, voor anderen doet het er niet zoveel toe. Dat de code die door de designer wordt gegenereerd geheel aan dit pattern voldoet, zie je direct terug in de designer zelf.

In het paarse vak rechtsboven: de in het vorige artikel behandelde  Data Source entiteiten vertegenwoordigen het Model
In het blauwe vak in het midden: de zogenaamde Visual Tree van schermelementen vertegenwoordigt de View
In het rode vak links: de weergave van Properties en Methods waarmee de View aan de Model wordt “gekoppeld” vertegenwoordigt de ViewModel

Het groene vak Properties rechtsonder tenslotte, heeft met MVVM niets te maken, maar heb ik straks nog vaak nodig voor aapassingen.

Screen Navigation

Ik kom later weer terug op de Screen Designer, maar om te weten wat er moet gebeuren is het natuurlijk wel prettig als ik even kan zien wat ik nu eigenlijk heb. Het enige dat ik hiervoor moet doen, is het nieuw gemaakte scherm, toevoegen aan het menu (de navigatie) van het scherm. Ik toets eenvoudigweg Ctrl+F5 om de applicatie te starten. Aangezien het SearchStudenten scherm het enige is dat ik gemaakt heb, krijg ik dat ook te zien:

image
Figuur 4: Mijn applicatie bij de eerste keer starten

De Ribbonbar aan de bovenkant en de menu-/navigatiebalk aan de linkerkant kom ik later op terug. Nu concetreer ik me even op het tabje “Search Studenten”. Hier zie je wat er runtime geworden is van de gegenereerde Visual Tree die je in Figuur 3 (de View) al even zag. Allereerst wil ik wat eenvoudige zaken aanpassen: aanwezige kolommen en de breedte daarvan. Alle zaken waarvoor ik alleen de visual tree (inclusief bijbehorende properties) wil aanpassen, kan ik doen door, terwijl de applicatie in Debug mode draait, op de knop Design Screen rechtsboven te klikken. Wat je dan krijgt is een designer van de View, inclusief een Preview scherm:

image
Figuur 5: Screen Designer in Debug mode

In de linker kolom van deze Designer kan je schermelementen toevoegen, verwijderen en wijzigen. Selecteer je een scherm-element, dan kan je rechtsonder de properties aanpassen.

Let wel op dat wat je op het scherm aanpast, ook echt bij het scherm hoort. Bijvoorbeeld: ik wil graag dat de kolom “Organisatie” op het scherm wordt getoond als “Sector”. Dat kan ik hier op dit scherm wel aanpassen, maar dan zal ik dat op alle schermen opnieuw moeten doen. In plaats daarvan kan ik dus beter naar de Data Source Designer gaan in Visual Studio, om daar de property “Display Name” aan te passen. Vanaf nu krijgt dit veld overal het label “Sector”:

image
Figuur 6: Property aanpassen in Data Source Designer

Om ruimte te besparen, wil ik in dit zoekscherm (en eigenlijk overal in de applicatie) Nummer, Roepnaam, Tussenvoegsel en Achgternaam in 1 kolom weergeven. Hoe dat kan, lees je in een afzonderlijke blog over Computed Columns.