>

onsdag 7 december 2011

Bli först med en app i Windows Store - tävling

Nu är det bestämt att Windows 8 beta kommer i februari. Samtidigt kommer Microsoft att släppa Windows Store som är ett Marketplace/AppStore för Windows 8 applikationer. Microsoft startar nu också en tävling där bidragen skall skickas in senast 8 januari 2012. För att ha chans att bli en av de åtta vinnarna behöver ditt program följa designmönstret metro och vara till stor nytta för användaren.
Om du vinner är en av priserna du kommer att få en Samsung Windows Developer Preview PC (den som delades ut under Build Windows konferensen), vilket kan tilläggas är en väldigt trevlig liten maskin och jag skulle inte ha nåt emot att ha två.


Låt oss börja koda, blir du eller jag en av vinnarna?
Här laddar du hem det du behöver för att starta och kan läsa om hela tävlingen.

torsdag 22 september 2011

Hur Menyer fungerar i Windows 8

Denna bloggpost grundar sig på Windows 8 Developer Preview release och kan komma att ändras.

I Windows 8 finns en ny standard på menyerna om du gör en Metro-stilad applikation. Menyer är nåt som inte behövs synas hela tiden vilket Microsoft har tagit fasta på, alla menyer är dolda. Om användaren vill se menyern drar den in fingret uppifrån eller nerifrån in på skärmen (båda gesterna ger samma resultat). Användaren kan också använda höger-musklick alternativt win+Z. Samt att du kan även öppna menyerna via kod. Menyerna ligger som en panel upptill och/eller nertill.

Som exempel kan vi titta på Internet Explorer för Windows 8. Den har en meny nertill där användaren kan skriva skriva in adressen till sidan den vill besöka. Den övre menyn används till för att kunna hoppa mellan de olika sidorna som är öppnade. När användaren använder sidan döljs båda menyerna och allt den ser är enbart sidan.

menusnonemenus

Menyerna får du utforma precis hur du vill. För att skapa en meny lägger du bara till ApplicationBar elementet i din XAML kod och sätter egenskapen VerticalAligment till Top eller Bottom. Inuti Elementet kan du sedan lägga dina vanliga XAML element, som tex knappar. Du får dessutom bestämma hur hög menyn skall vara.

Denna bloggpost grundar sig på Windows 8 Developer Preview release och kan komma att ändras.

onsdag 21 september 2011

Filhantering i Windows 8

Denna bloggpost grundar sig på Windows 8 Developer Preview release och kan komma att ändras.

I Windows 8 kommer applikationerna att vara mera avgränsade, både mellan varandra och systemet. Detta innebär bl.a. att filhanteringen kommer var lite annorlunda än du är van vid.
Ersättaren till IsolageStorage
Till att börja med har applikationen ett eget mapp att använda ungefär på samma sätt som IsolageStorage fungerar. Windows.Storage.ApplicationData.Current.LocalFolder ger denna mapp. Via den kan du sedan skapa och öppna filer.
Jobba med biblioteken
Det andra alternativet du har om du vill öppna filer är genom det som vi idag lärt känna som Bibliotek/Library. Dessa mappar kan du nå via Windows.Storage.KnownFolders och är någon utav följande:

  • PicturesLibrary
  • MusicLibrary
  • DocumentsLibrary
  • VideoLibrary
Här finns även RemovableDevices vilket gör att du kan nå tex ett USB-minne. Dock kan du inte nå någon av ovanstående innan du deklarerat att du vill ha åtkomst till dem. Detta görs via manifestet och kommer då också att visas för användaren.
Library
Och som vanligt skall du inte begära mer behörighet än du behöver.
Låt användaren bestämma
Om du vill komma åt filer utöver dessa platser kan du fråga användaren efter filer och på det sättet få åtkomst till den. Detta gör du med hjälp av Windows.Storage.Pickers.FileOpenPicker, denna öppnar ett standardgränssnitt som låter användaren välja en fil eller flera filer. Dessa kan komma från den lokala datorn, någon dator i nätverket eller en annan applikation som stöder funktionen att dela med sig av filer.
När en fil blir öppna på detta sätt har din applikation bara åtkomst till filen just då, du kan alltså inte spara sökvägen och försöka öppna filen nästa gång du har applikationen igång. För att kunna göra detta kan man spara undan att användaren har gett applikationen tillstånd att använda filen. Detta görs i Windows.Storage.AccessCache.StorageApplicationPermissions.FutureAccessList. På detta objekt använder du funktionen AddOrReplace för att lägga till och spara en filaccess för, att sedan kolla i objektet efter om du redan har en behörighet sparad använder du funktionen ContainsItem och för att sedan återhämta filobjektet används GetFileAsync funktionen.

Denna bloggpost grundar sig på Windows 8 Developer Preview release och kan komma att ändras.

onsdag 14 september 2011

Windows 8, en första titt

Windows 8 kommer att innebära stora förändringar, både för dig som utvecklare och också användare. Förutom det mest uppenbara med gränssnitten finns många smarta finesser under ytan. Som användare signar du in med ditt livekonto och dina inställningar hänger med konto vilket gör att om du signar in på en annan Windows 8 maskin får du dina inställningar. Du kommer också kunna access alla dina datorer genom kopplingen med ditt livekonto. Sök funktionen har även i Windows 8 fått en central plats och det finns möjlighet att integrera det med applikationerna som du skriver. När du vill utföra ett sök har du en ruta att skriva i och sedan en lista på applikationer att välja mellan inklusive filer, inställningar och applikationer.


Sök är ett exempel på ett kontrakt. Kontrakt används för att kunna få program att samarbeta utan att behöva känna till varandra innan. Share (dela) är ett annat exempel på ett kontrakt om du vill använda det kontraktet kan du antingen stödja att dela till din applikation t.ex. om du skriver en facebook applikation så kan du tillåta att man kan skicka bilder från en annan applikaiton. Eller så kan du stödja att man kan dela från din applikation t.ex. från en fotoeditor eller liknande.

När du designar dina applikationer så kommer du ha några mallar att tillgå för att underlätta för dig att göra en windows 8 applikation eftersom du egentligen har en blank tom skärm att utgå från. Ingen start meny som skall ha en den av (vanligtvis) undre delen av skärmen, ingen övre del av applikationen som är reserverad för mininmera, maximera och stängknapp. Tänket bakom att designa en windows 8 applikation är fokus på innehållet och allt klutter skall bort, dock får det gärna göras vackert. Alla kommandon kan och skall gömmas på menyer som inte syns förrän man i touch mode gör en gest eller högerklick med muspekaren.

Det händer alltså mycket för oss utvecklare i Windows 8 och detta är bara en kort introduktion, jag har inte ens börjat skrapa på ytan.

tisdag 13 september 2011

Build the future

På plats i Anaheim följer jag nog vad som händer med framtidens utveckling och vad Windows 8 kommer att innebära för oss utvecklare. Även du kan följa keynote live

fredag 20 maj 2011

Förstå lambda

Lambda kan vara ett smidigt sätt att få koden kortare och mera lättläst, förutsatt att du förstår lambda, vilket jag hoppas du skall efter att ha läst detta.

Utan Lambda
Följande exempel använder en delegat (countSelection) som inparameter för att avgöra vilka filer som skall räknas i en given mapp. Delegaten innehåller alltså en funktion som körs när variabelnamnet används (countSelection(file))

  1. public int CountFiles(String path, FileFilter countSelection)
  2. {
  3.     DirectoryInfo dir = new DirectoryInfo(path);
  4.     FileInfo[] allFiles = dir.GetFiles();
  5.     int fileCount = 0;
  6.     foreach (var file in allFiles)
  7.         if (countSelection(file))
  8.             fileCount++;
  9.     return fileCount;
  10. }

För att kunna använda funktionen behöver jag veta hur delegaten FileFilter ser ut:
  1. public delegate bool FileFilter(FileInfo file);

Och sedan skapa en funktion som har samma signatur:
  1. public bool TxtFilter(FileInfo fileToTest)
  2. {
  3.     if (fileToTest.Extension == ".txt")
  4.         return true;
  5.     return false;
  6. }

Nu kan jag anropa funktionen genom att ange att det är TxtFilter som skall användas:
  1. CountFiles("c:\\tmp", TxtFilter);

Nästa gång vill jag använda CountFiles med ett annat filter får jag skapa en ny funktion:
  1. public bool LastDayFilter(FileInfo fileToTest)
  2. {
  3.     if (fileToTest.LastAccessTime > DateTime.Now.AddDays(-1))
  4.         return true;
  5.     return false;
  6. }

För att sedan ange den som delegat till anropet:
  1. CountFiles("c:\\tmp", LastDayFilter);

Infoga Lambdat

Koden bli nu inte så lättläst och funktionerna TxtFilter och LastDayFilter skapas alltså bara för att kunna anropa CountFiles funktionen. Det vi kan göra med Lambda är att ta bort dessa "delegat-funktioner" (TxtFilter och LastDayFilter) och istället skriva dessa funktioner direkt i CountFiles anropet. Ungefär så här:

  1. CountFiles("c:\\tmp",  
  2.     public bool TxtFilter(FileInfo fileToTest)
  3.     {
  4.         if (fileToTest.Extension == ".txt")
  5.             return true;
  6.         return false;
  7.     }
  8. );

Detta är dock inte giltig kod, låt oss fixa det. När du skriver siffran 3 som inparameter till en funktion anger du ju inte vad den skall heta vid anropet t.ex. foo(3) detta gäller även för lambda, vi tar bort ordet TxtFilter. Access nivån (public) har inte heller nån betydelse liksom att specificera returvärdet. Att funktionen/lambdat skall returnera en bool är redan definierat av inparameter typen (FileFilter).

Så låt oss ta bort dessa tre. Jag skall också lägga till en avskiljare mellan inparametrar och funktionskroppen i formen av en pil:

  1. CountFiles("c:\\tmp" ,  
  2.     (FileInfo fileToTest)
  3.     =>
  4.     {  
  5.         if (fileToTest.Extension == ".txt")   
  6.             return true ;  
  7.         return false ;
  8.     }
  9. );

Detta är ett giltigt lambda (liksom de resterande i posten). Dock är idén med lambda att det skall vara kort och lättläst så låt oss korta ner lite, vi börjar med inparameterdelen. Funktionen som skall skickas in i CountFiles måste ha en inparamter av typen FileInfo (definierat av FileFilter), därför behöver vi inte skriva ut det. När funktionen består av bara en inparameter behövs inte heller parenteserna och det sista vi kan göra för att korta ner ordentligt är att använda ett kort namn, t.ex. f:

  1. CountFiles("c:\\tmp",  
  2.    f
  3.    =>
  4.     {
  5.         if (f.Extension == ".txt")
  6.             return true;
  7.         return false;
  8.     }
  9. );

Funktionsdelen kan vi också korta ner, låt oss börja med att skriva om if-satsen:

  1. CountFiles("c:\\tmp",
  2.    f
  3.    =>
  4.    {
  5.        return f.Extension == ".txt";
  6.    }
  7. );

När funktionsdelen består av enbart en rad kan vi stryka {  } och ; samt även return nyckelordet (det är redan givet från FileFilter att vi skall returnera en bool). Låt oss även ta bort några radbrytningar:

  1. CountFiles("c:\\tmp", f => f.Extension == ".txt");

Och där har vi nu ett snyggt lambda. Lambdat är en funktion som är namnlös och skickas direkt in i inparametern till CountFiles. f är inparameter i denna funktion och det som står till höger om => är själva funktionen. Funktionsanropet till CountFiles är nu mer lätt läst kod och kan utläsas ungefär som: "Räkna alla filer i tmp katalogen där filerna har txt ändelsen.".

tisdag 8 februari 2011

Ta bort snabbkommando

När du designar ditt program till att innehålla snabbkommandon kan du ibland råka på att använda ett kommando som har ett standard beteende i en speciell kontroll vilket gör att ditt kommando inte fungerar när just den kontrollen är i fokus. Vad är då lösningen till detta?

Tillexempelvis i en RichTextBox  finns snabbkommandot Ctrl+B för att använda fetstil på texten. Väljer du då att använda Ctrl+B som ett snabbkommando i ditt program har vi problem. Då kommer fetstil att aktiveras om du har RichTextBoxen i fokus istället för att ditt kommando körs.

<Window.InputBindings> 
        <KeyBinding Gesture="Ctrl+B" Command="MyCommands.Choose"/> 
</Window.InputBindings>

Det du behöver göra är att få RichTextBoxen att ignorera Ctrl+B vilket du gör genom att sätta en InputBinding på denna och ange att kommandot ApplicationCommands.NotACommand.

<RichTextBox> 
  <RichTextBox.InputBindings>
    <KeyBinding Gesture="Ctrl+B" Command="ApplicationCommands.NotACommand"/>
  </RichTextBox.InputBindings>  
</RichTextBox>