Featured Image
Oct 10, 2010 2 min read 1 comments

[PL] Entity Framework i SQLite

Obecnie do składowania danych wykorzystuję pliki XML. Generyczna klasa abstrakcyjna AbstractDataAccess zajmuje się serializacją i deserializacją odpowiednich danych. Postanowiłem jednak wykorzystać Entity Framework w połączeniu z SQLite do składowania danych. Głównie dlatego, że wolę skorzystać z gotowego mechanizmu zapisu/odczytu niż dalej rozwijać coś własnego. Z Entity Framework miałem już do czynienia podczas pracy inżynierskiej. Użyłem wtedy pierwszej wersji EF, a teraz chciałbym zobaczyć jak wygląda w praktyce wersja 4.0. W celu połączenia EF i SQLite będziemy potrzebować odpowiedniego providera. Ja wykorzystałem System.Data.SQLite, który jest providerem EF o otwartym kodzie źródłowym. Wystarczy pobrać instalator, a następnie oczywiście zainstalować. Po instalacji będziemy mogli połączyć się z naszą bazą SQLite przy pomocy Visual Studio: Wystarczy przejść do okna “Server Explorer” i dodać odpowiednie połączenie do bazy danych. Proces dodawania połączenia jest bardzo intuicyjny. Dla użytkowników Firefoxa polecam instalacje dodatku SQLite Manager. Dodatek daje większe możliwości zarządzania SQLite niż Visual Studio. SQLite Manager jest też moim zdaniem wygodniejszy w użyciu. Wygenerowany model EF na podstawie bazy danych DotBeer’a przedstawia się następująco: Na pewno podczas dalszego rozwoju projektu, model i jak sama baza danych ulegną jeszcze zmianie. Tutaj można pobrać źródła przykładowego projektu jaki stworzyłem. Bazę danych należy przenieść na dysk C lub przenieść w dowolne miejsce, a potem odpowiednio zedytować ConnectionString w pliku konfiguracyjnym. Niestety baza danych jest jeszcze pusta. Będę musiał niedługo przenieść dane z plików XML. PS. Zna ktoś może jakieś narzędzie do generowania diagramów ERD z SQLite? AbstractDataAccessaa

Featured Image
Oct 3, 2010 1 min read 1 comments

[PL] Productivity Power Tools

Productivity Power Tools jest dodatkiem do Visual Studio, który znacząco rozbudowuje jego możliwości. Poniżej wymieniłem kilka zmian jakie wprowadzana narzędzie: dostęp do nowego okienka "Add Reference". Wygląda ono tak: Co w nim takiego fajnego? Zaznaczanie dodanych już Assemblies zielonym ptaszkiem, możliwość wyszukiwania po nazwie, większe możliwości sortowania. Dodać należy również, że okno nie odświeża listy za każdym jego odtworzeniem jak to ma miejsce w "gołym" Visual Studio. podświetlanie bieżącej linii. Proste a jakże przydatne! możliwość przypinania plików. Wygląda to w ten sposób: Do menu kontekstowego pliku doszła opcja "Close All But Pined". Przydatna funkcja moim zdaniem, gdy potrzebujemy mieć przez jakiś czas szybszy dostęp do określonego pliku. automatyczne kończenie następujących znaków: (), {}, [], <>, "" oraz ”. Przydatne, bo zwyczajnie oszczędzamy czas i klawiaturę. Pełna lista możliwości dodatku znajduje się na stronie projektu. Zachęcam do jej zapoznania, gdyż przytoczyłem tutaj tylko kilka możliwości narzędzia.

Featured Image
Oct 3, 2010 1 min read 2 comments

[PL] pisanie dokumentacji z GhostDoc

W kodzie C# możemy tworzyć komentarze przy pomocy XML. Na podstawie tych komentarzy można później wygenerować pliki z dokumentacją przy pomocy odpowiednich narzędzi. Zawsze jednak strasznie nie chciało mi się  pisać komentarzy do kodu. Zajęcie to jest nudne i czasochłonne (czasem nic po prostu nie przychodzi do głowy). Z GhostDoc (dodatek do Visual Studio) wszystko może ulec zmianie. Narzędzie to służy do generowania komentarzy XML za nas. Jak sam autor zaznacza w prezentacji, GhostDoc nie czyta w myślach (jaka szkoda!). Zdarzyć się może, że narzędzie wygeneruje jakiś kompletnie bezsensowny komentarz. Jednak kilka pierwszych testów wykonanych przeze mnie było pomyślnych. Przykładowy komentarz wygenerowany przez narzędzie do metody Save w klasie HeroComponent wygląda następująco: /// &lt;summary&gt; /// Saves the specified hero. /// &lt;/summary&gt; /// &lt;param name=&quot;hero&quot;&gt;The hero.&lt;/param&gt; public static void Save(Hero hero) { ... } Mi taki komentarz w zupełności wystarcza. Z pewnością będą używać GhostDoc do dalszego komentowania kodu. PS. Autor prezentacji ma chyba najbardziej nudny głos jaki kiedykolwiek słyszałem. Udało się komuś nie ziewnąć podczas oglądania? 😉

Featured Image
Sep 26, 2010 1 min read 1 comments

[PL] Visual Studio tip: wyłączenie zooma przy CTRL + scroll myszy

W Visual Studio możemy zmieniać wartość powiększenia edytora kodu poprzez CTRL + scroll myszy. Obecna wartość powiększenia wyświetlana jest w lewym dolnym rogu. Osobiście nigdy nie miałem potrzeby zmiany wielkości powiększenia bo odpowiada mi domyślna wartość. Jednak bardzo często udawało mi się niezamierzenie użyć wspomnianego na początku skrótu. Sytuacja ta była na tyle denerwująca, że postanowiłem poszukać rozwiązania tej sytuacji. Samo Visual Studio niestety nie posiada możliwości wyłączenia tego skrótu. Jedynym wyjściem jest instalacja rozszerzenia o dźwięcznej nazwie Disable Mouse Wheel Zoom. Po instalacji rozszerzenia już nigdy więcej niechcący nie zmienimy sobie wartości powiększenia edytora. Oh yeah!

Featured Image
Sep 26, 2010 1 min read 2 comments

[PL] Visual Studio tip: Go To Definition

Visual Studio posiada opcje, która pozwoli przenieść się do fragmentu kodu gdzie została zdefiniowana dana zmienna. Wystarczy zaznaczyć daną zmienną i wybrać z menu kontekstowego opcję “Go To Definition”. To samo można osiągnąć wciskając domyślnie zdefiniowany klawisz F12. Jednak oba sposoby nie było dla mnie zbyt wygodne. W Visual Studio Gallery możemy znaleźć małe rozszerzenie, które rozwiązuje ten problem. Po instalacji rozszerzenia będziemy mogli przejść do definicji zmiennej przy pomocy CTRL + klik lewym klawiszem myszy. Niby nic ale dla mnie jest to szalenie wygodne.

Featured Image
Sep 19, 2010 1 min read 2 comments

[PL] implementacja interfejsu INotifyPropertyChanged poprzez refleksję

Korzystanie z interfejsu INotifyPropertyChanged podczas pracy z WPF to praktycznie codzienność. Za którymś razem jednak implementacja tego interfejsu w kolejnej klasie może już zbrzydnąć. Dlaczego, więc nie skorzystać z refleksji i extensions methods? Metodę wywołującą zdarzenie PropertyChanged napiszemy raz i będziemy z niej korzystać do woli. Implementacja tej metody w moim wykonaniu wygląda następująco: public static class INotifyPropertyChangedExtension { public static void OnPropertyChanged(this INotifyPropertyChanged sender, string propertyName) { Type type = sender.GetType(); while (type != null) { FieldInfo eventFieldInfo = type.GetField(&quot;PropertyChanged&quot;, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy | BindingFlags.Instance); if (eventFieldInfo != null) { MulticastDelegate eventDelegate = eventFieldInfo.GetValue(sender) as MulticastDelegate; if (eventDelegate != null) { eventDelegate.DynamicInvoke(new object[] { sender, new PropertyChangedEventArgs(propertyName) }); break; } } type = type.BaseType; } } } Najważniejsza w tym przypadku jest pętla. Dzięki niej będziemy w stanie wywołać zdarzenie PropertyChanged z klas potomnych. Taka sytuacja w projekcie DotBeer ma miejsce np. w klasie OptionsWindowViewModel, która dziedziczy po klasie bazowej ViewModelBase.

Featured Image
Sep 19, 2010 1 min read 4 comments

[PL] Visual Studio tip: przydatne skróty klawiszowe

W tej notce przedstawię kilka przydatnych skrótów klawiszowych, który używam codziennie (lub prawie codziennie ;)) podczas pracy z Visual Studio. CTRL + E, D – formatowanie kodu w aktywnym pliku, CTRL + SPACEBAR – wywołanie IntelliSense, CTRL + E, C – komentowanie zaznaczonych linii kodu, CTRL + E, U – odkomentowanie zaznaczonych linii kodu, CTRL + SHIFT + L – kasowanie zaznaczonych linii kodu, CTRL + M, O – zwinięcie wszystkich bloków kodu, CTRL + M, L – rozwinięcie wszystkich bloków kodu, CTRL + R, CTRL + W – pokazywanie białych znaków, CTRL + K, X – wstawianie code snippet, CTRL + K, S – otoczenie zaznaczonego kodu danym code snippet, CTRL + } – przechodzenie do otwierającego/zamykającego nawiasu/klamerki/regionu, F5 – start aplikacji wraz z rozpoczęciem debugowania, CTRL + F5 – start aplikacji bez rozpoczęcia debugowania, SHIFT + F5 – zatrzymanie debugowania, CTRL + SHIFT + B / F6 – skompilowanie projektu, CTRL + BREAK – zatrzymanie kompilacji projektu. Opis wszystkich skrótów klawiszowych możemy znaleźć w dokumentacji. Warto sobie również ściągnąć plakat ze skrótami klawiszowymi i powiesić nad biurkiem 🙂 A jakich Wy jeszcze używacie skrótów klawiszowych? IntelliSense

Featured Image
Sep 5, 2010 2 min read 2 comments

[PL] Visual Studio: zarządzanie code snippets

W Visual Studio możemy wstawiać tzw. code snippets. Są to ustalone kawałki kodu zawierające najczęściej używane konstrukcje. W celu wstawienia snippeta należy wywołać menu kontekstowe w edytorze tekstu i wybrać “Insert Snippet” albo “Surround With”. Różnica między tymi dwoma opcjami jest taka,  że “Surround With” otoczy zaznaczony kawałek kodu danym snippetem. Poniżej został przedstawiony zrzut ekranu z menu kontekstowego: Co jednak w przypadku, gdy chcielibyśmy zdefiniować własny code snippet? Wtedy musimy doinstalować dodatek Snippet Designer. Pozwoli on nam na wyeksportowanie dowolnego kawałka kodu jako snippeta. Najpierw należy zaznaczyć dany kawałek kodu, który chcemy wyeksportować, a następnie z menu kontekstowego wybrać opcje “Export as Snippet”. Zostanie otworzony edytor naszego snippeta. Snippet zapisujemy do domyślnego folderu – w moim przypadku będzie to “C:\Users\Damian\Documents\Visual Studio 2010\Code Snippets\Visual C#\My Code Snippets”. Ja wyeksportowałem sobie taki kawałek kodu: #region private members #endregion #region properties #endregion #region constructors #endregion #region public methods #endregion #region private methods #endregion Wstawiam go do każdej nowo utworzonej klasy w projekcie. Dzięki temu mam logicznie pogrupowane elementy danej klasy. Pomaga to przy jej tworzeniu i późniejszym rozwoju. Wstawianie naszego nowego snippeta (nazwałem go “Regions”) odbywa się oczywiście poprzez menu kontekstowe. Został on zapisany do katalogu “My Code Snippets”: Co jeśli chcemy zmienić miejsce przechowywania naszych plików ze snippetami i mieć do nich dostęp z menu kontekstowego? Wtedy musimy przejść do Tools -> Code Snippet Manager. Otworzone zostanie następujące okno: Wybieramy “Add”, a następnie wskazujemy katalog, w którym przechowujemy pliki ze snippetami. Zmiany w katalogu zostaną odzwierciedlone automatycznie w menu kontekstowym. Możemy więc przez przeszkód umieszczać we wskazanym katalogu nowe pliki ze snippetami. Dla osób posiadających wersję Express Visual Studio polecam przyjrzeć się projektowi Snippet Editor. W przeciwieństwie do Snippet Designer, nie integruje się on z Visual Studio tylko działa jako samodzielna aplikacja.

Featured Image
Sep 5, 2010 8 min read 5 comments

[PL] Visual Studio: File Header Add-Inn

Ostatnio zainstalowałem sobie narzędzie StyleCop, które służy do analizy kodu C# pod kątem przestrzegania ustalonego stylu kodowania. Wśród olbrzymiej ilości błędów jakie zostały zwrócone przez narzędzie, był błąd SA1633: FileMustHaveHeader. Błąd informuje nas o braku nagłówka w danym pliku. Nagłówek musi znajdować się na początku pliku i mieć następującą postać: //----------------------------------------------------------------------- // &lt;copyright file=&quot;NameOfFile.cs&quot; company=&quot;CompanyName&quot;&gt; // Company copyright tag. // &lt;/copyright&gt; //----------------------------------------------------------------------- W celu dodania takiego nagłówka do każdego pliku CS w projekcie, najłatwiej byłoby napisać własne makro w Visual Studio. Niestety makra możemy pisać jedynie w VB, a mnie interesowało użycie C#. Postanowiłem, więc napisać prostego Add-Inn’a, który będzie dodawać nagłówek do pliku. Podstawy tworzenia Add-Inn’a są opisane w dokumentacji. Po przebrnięciu przez wizzarda dostajemy szkielet naszego Add-Inn’a. Domyślnie została stworzona klasa Connect, która jest sercem całego projektu. Implementuje ona kilka metod, z których interesują nas OnConnection, QueryStatus oraz Exec. Metoda OnConnection wywoływana jest w momencie załadowania Add-Inn’a do Visual Studio. Jej implementacja wygląda następująco: public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom) { this.applicationObject = (DTE2)application; this.addInInstance = (AddIn)addInInst; if (connectMode == ext_ConnectMode.ext_cm_UISetup) { object[] contextGUIDS = new object[] { }; Commands2 commands = (Commands2)this.applicationObject.Commands; //Place the command on the tools menu. //Find the MenuBar command bar, which is the top-level command bar holding all the main menu items: CommandBar menuBarCommandBar = ((CommandBars)this.applicationObject.CommandBars)[&quot;MenuBar&quot;]; //Find the Tools command bar on the MenuBar command bar: CommandBarControl toolsControl = menuBarCommandBar.Controls[&quot;Tools&quot;]; CommandBarPopup toolsPopup = (CommandBarPopup)toolsControl; //This try/catch block can be duplicated if you wish to add multiple commands to be handled by your Add-in, //just make sure you also update the QueryStatus/Exec method to include the new command names. try { //Add a command to the Commands collection: Command command = commands.AddNamedCommand2(addInInstance, &quot;AddHeader&quot;, &quot;Add header to files&quot;, &quot;Add header to all CS files in solution&quot;, false, 1, ref contextGUIDS, (int)vsCommandStatus.vsCommandStatusSupported + (int)vsCommandStatus.vsCommandStatusEnabled, (int)vsCommandStyle.vsCommandStylePictAndText, vsCommandControlType.vsCommandControlTypeButton); //Add a control for the command to the tools menu: if ((command != null) &amp;&amp; (toolsPopup != null)) command.AddControl(toolsPopup.CommandBar, 1); } catch (System.ArgumentException ex) { //If we are here, then the exception is probably because a command with that name // already exists. If so there is no need to recreate the command and we can // safely ignore the exception. Debug.WriteLine(ex.ToString()); } } } Na początku pobieramy referencję do interfejsów DTE2 oraz AddInn. Interfejs DTE2 zapewni nam m.in. dostęp do GUI Visual Studio oraz solucji. W dalszej części metody pobieramy referencję do menu “Tools”, a następnie dodajemy tam nową pozycję przy pomocy metody AddNamedCommand2. Nasza nowa pozycja w menu będzie miała nazwę “Add header to files” oraz będzie wyświetlała ikonkę praw autorskich. Sposób na dodanie własnej ikonki został opisany w dokumentacji. Nasza pozycja w menu “Tools” będzie wyglądać następująco: Następnie musimy zwrócić uwagę na implementację metody QueryStatus: public void QueryStatus(string commandName, vsCommandStatusTextWanted neededText, ref vsCommandStatus status, ref object commandText) { if (neededText == vsCommandStatusTextWanted.vsCommandStatusTextWantedNone) { if (commandName == &quot;FileHeaderAddin.Connect.AddHeader&quot;) { status = vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled; return; } } } Metoda ta jest wywoływana, gdy użytkownik zacznie używać menu Visual Studio. Należy do zmiennej “status” przypisać odpowiednią wartość w zależności czy w danym momencie wspieramy wywołanie naszego Add-Inn’a. Zmienna “commandName” zawiera nazwę polecenia jakie zostało wybrane z menu. W metodzie OnConnection dodaliśmy tylko jedno polecenie o nazwie “AddHeader”. Najważniejsza metodą jest metoda Exec: public void Exec(string commandName, vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled) { handled = false; if (executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault) { if (commandName == &quot;FileHeaderAddin.Connect.AddHeader&quot;) { handled = true; if (this.formMain == null || this.formMain.IsDisposed) { this.formMain = new FormMain(this.applicationObject); } formMain.Show(); return; } } } Zostaje ona wywołana w momencie kliknięcia na pozycję w menu. Również i w tej metodzie musimy sprawdzić zawartość zmiennej “commandName”. W mojej implementacji metody tworzony jest nowy formularz Windows Forms, do którego przekazywana jest zmienna “applicationObject”. Wygląd formularza jest następujący: Funkcjonalność formularza jest dość intuicyjna, więc zajmiemy się teraz kodem. W konstruktorze formularza tworzony jest obiekt mojej klasy HeaderManager. Klasa ta zawiera jedną publiczna metodę oraz trzy zdarzenia: #region private members private DTE2 applicationObject; private int filesProcessed = 0; private int filesCount = 0; #endregion #region properties public event EventHandler&lt;AddHeaderToFilesStartedEventArgs&gt; AddHeaderToFilesStarted; public event EventHandler&lt;OnAddHeaderToFilesProgressChanged&gt; AddHeaderToFilesProgressChanged; public event EventHandler&lt;AsyncCompletedEventArgs&gt; AddHeaderToFilesCompleted; #endregion #region constructors public HeaderManager(DTE2 applicationObject) { this.applicationObject = applicationObject; } #endregion #region public methods public void AddHeaderToFilesAsync() { ThreadPool.QueueUserWorkItem((state) =&gt; this.AddHeaders()); } #endregion Starałem się tutaj trzymać tutaj zasad Event-based Asynchronous Pattern. Właściwe dodawanie nagłówków rozpoczyna się w metodzie AddHeaders: private void AddHeaders() { this.filesCount = this.GetFilesCount(); this.filesProcessed = 0; this.OnAddHeaderToFilesStarted(new AddHeaderToFilesStartedEventArgs(this.filesCount)); this.AddHeaderToFiles(); this.OnAddHeaderToFilesCompleted(new AsyncCompletedEventArgs(null, false, null)); } Wywoływana jest tutaj na początku metoda GetFilesCount, która oblicza ilość plików CS jakie znajdują się w bieżącej solucji: private int GetFilesCount() { int filesCount = 0; Solution solution = this.applicationObject.Solution; foreach (Project project in solution.Projects) filesCount += this.GetFilesCountForProject(project.ProjectItems); return filesCount; } private int GetFilesCountForProject(ProjectItems projectItems) { int filesCount = 0; foreach (ProjectItem projectItem in projectItems) { if (projectItem.SubProject != null &amp;&amp; projectItem.SubProject.ProjectItems != null &amp;&amp; projectItem.SubProject.ProjectItems.Count &gt; 0) { filesCount += GetFilesCountForProject(projectItem.SubProject.ProjectItems); } else if (projectItem.ProjectItems != null &amp;&amp; projectItem.ProjectItems.Count &gt; 0) { filesCount += GetFilesCountForProject(projectItem.ProjectItems); } if (projectItem.Name.EndsWith(&quot;.cs&quot;)) filesCount++; } return filesCount; } Metoda GetFilesCount iteruje po wszystkich projektach w danej solucji i wywołuje kolejna metodę GetFilesCountForProject. Ta ostatnia metoda zajmuje się iteracją po wszystkich obiektach danego projektu. Uwzględnione zostało tutaj przechodzenie w głąb drzewa danego projektu. Jeśli nazwa danego obiektu w projekcie kończy się na “.cs” (czyli jest to plik z kodem C#) jest on zliczany. Po metodzie GetFilesCount wywoływana jest kolejna metoda AddHeaderToFiles: private void AddHeaderToFiles() { Solution solution = this.applicationObject.Solution; foreach (Project project in solution.Projects) this.AddHeaderToFilesInProject(project.ProjectItems); } private void AddHeaderToFilesInProject(ProjectItems projectItems) { foreach (ProjectItem projectItem in projectItems) { if (projectItem.SubProject != null &amp;&amp; projectItem.SubProject.ProjectItems != null &amp;&amp; projectItem.SubProject.ProjectItems.Count &gt; 0) { this.AddHeaderToFile(projectItem); this.AddHeaderToFilesInProject(projectItem.SubProject.ProjectItems); } else if (projectItem.ProjectItems != null &amp;&amp; projectItem.ProjectItems.Count &gt; 0) { this.AddHeaderToFile(projectItem); this.AddHeaderToFilesInProject(projectItem.ProjectItems); } else { this.AddHeaderToFile(projectItem); } } } Metoda AddHeaderToFiles również iteruje po wszystkich projektach w danej solucji i wywołuje metodę AddHeaderToFilesInProject. Ta ostatnia metoda przechodzi po drzewku danego projektu i wywołuję metodę AddHeaderToFile, która zajmuje się dodawaniem nagłówka do danego pliku: private bool IsFileAutoGenerated(string filePath) { if (filePath.Contains(&quot;.Designer.cs&quot;)) return true; using (StreamReader streamReader = new StreamReader(new FileStream(filePath, FileMode.Open))) { foreach (string line in streamReader.ReadAsLines().Take(10)) if (line.Contains(&quot;&lt;auto-generated&gt;&quot;)) return true; } return false; } private void AddHeaderToFile(ProjectItem projectItem) { if (projectItem.Name.EndsWith(&quot;.cs&quot;)) { string filePath = projectItem.Properties.Item(&quot;FullPath&quot;).Value.ToString(); if (File.Exists(filePath) &amp;&amp; !this.IsFileAutoGenerated(filePath)) { string section = &quot;------------------------------------------------------------------------------&quot;; string commentString = @&quot;//&quot;; FileStream fileStream = File.Open(filePath, FileMode.Open); StreamReader streamReader = new StreamReader(fileStream); List&lt;string&gt; lines = new List&lt;string&gt;(streamReader.ReadAsLines()); //check if header already exists if (lines[0] == commentString + section) //header exists, skip it lines = new List&lt;string&gt;(lines.Skip(8)); streamReader.Close(); fileStream = File.Open(filePath, FileMode.Create); StreamWriter streamWriter = new StreamWriter(fileStream); streamWriter.WriteLine(commentString + section); streamWriter.WriteLine(String.Format(&quot;{0} &lt;copyright file=\&quot;{1}\&quot; company=\&quot;{2}\&quot;&gt;&quot;, commentString, projectItem.Name, HeaderSettings.Default.CompanyName)); streamWriter.WriteLine(String.Format(&quot;{0} {1}&quot;, commentString, HeaderSettings.Default.Copyright)); streamWriter.WriteLine(commentString + &quot; &lt;/copyright&gt;&quot;); streamWriter.WriteLine(String.Format(&quot;{0} &lt;author&gt;{1}&lt;/author&gt;&quot;, commentString, HeaderSettings.Default.Author)); streamWriter.WriteLine(String.Format(&quot;{0} &lt;email&gt;{1}&lt;/email&gt;&quot;, commentString, HeaderSettings.Default.Email)); streamWriter.WriteLine(commentString + section); streamWriter.WriteLine(); streamWriter.WriteLines(lines); streamWriter.Flush(); streamWriter.Close(); this.filesProcessed++; this.OnAddHeaderToFilesProgressChanged(new OnAddHeaderToFilesProgressChanged(this.filesProcessed)); } } } Na początku sprawdzane jest czy nazwa pliku kończy się na “.cs”, a następnie czy ten plik w ogóle istnieje. Właściwość Properties klasy ProjectItem zapewnia dostęp do informacji jakie możemy wyczytać w okienku Properties w Visual Studio. Nas interesuje pozycja “Full Path”, która zawiera ścieżkę do pliku. Dostęp do tej wartości możliwy jest poprzez użycie metody Item. W metodzie IsFileAutoGenerated sprawdzane jest czy dany plik został wygenerowany automatycznie przez jakieś narzędzie. Dodawanie nagłówka w takich plikach nie ma sensu, ponieważ wprowadzone zmiany i tak zostaną nadpisane przy następnym użyciu narzędzia, które ten plik wygenerowało. Metoda IsFileAutoGenerated sprawdza najpierw czy w nazwie pliku znajduję się łańcuch “.Designer.cs”. Jeśli go nie ma pobierane jest pierwsze 10 linii i następuje sprawdzenie pod kątem istnienia łańcucha “<auto-generated>”. Przykładowy nagłówek stworzony przez generator plików “settings” w Visual Studio wygląda następująco: //------------------------------------------------------------------------------ // &lt;auto-generated&gt; // This code was generated by a tool. // Runtime Version:4.0.30319.1 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // &lt;/auto-generated&gt; //------------------------------------------------------------------------------ W dalszej części metody AddHeaderToFile następuje sprawdzenie czy w danym pliku istnieje już nagłówek. Jeśli tak to pomijane jest pierwsze 8 linii. Metoda ta nie jest doskonała ponieważ sprawdzana jest jedynie pierwsza linia danego pliku. W dalszej części metody następuje już dodanie nagłówka do pliku. Wynikiem działania metody AddHeaderToFile będzie dodanie nagłówka o następującej postaci: //------------------------------------------------------------------------------ // &lt;copyright file=&quot;ApplicationPaths.cs&quot; company=&quot;Damian Antonowicz&quot;&gt; // copyright © 2010 Damian Antonowicz // &lt;/copyright&gt; // &lt;author&gt;Damian Antonowicz&lt;/author&gt; // &lt;email&gt;poczta@damianantonowicz.pl&lt;/email&gt; //------------------------------------------------------------------------------ Przedstawiony Add-Inn można łatwo rozbudować o dodawanie komentarzy np. do plików HTML lub XAML. Tutaj znajduje się projekt mojego Add-Inn’a. W celu jego instalacji należy oczywiście najpierw projekt skompilować 😉 Następnie z katalogu projektu kopiujemy plik “FileHeaderAddin.AddIn” do katalogu, w którym Visual Studio przechowuje pliki “AddInn”. W moim przypadku (Windows 7) będzie to katalog “C:\Users\Damian\Documents\Visual Studio 2010\Addins”. Następnie “FileHeaderAddin.AddIn” należy otworzyć w edytorze tekstu i znaleźć węzeł <Assembly></Assembly>. Należy w nim podać pełną ścieżkę do DLL z Add-Inn’em. Na końcu odpalamy Visual Studio i przechodzimy do menu Tools -> Add-In Manager. Zaznaczamy pole przy nazwie Add-Inn’a i klikamy na “OK”. Add-Inn w tym momencie powinien się załadować.

Featured Image
Aug 25, 2010 1 min read 2 comments

[PL] Visual Studio tip: task list

W kodzie projektu możemy dodawać komentarze, które następnie mogą zostać wyświetlone w oknie Task List w Visual Studio. Domyślnie mamy dostępne trzy tokeny, które możemy użyć: TODO, HACK, or UNDONE. Poniżej został przedstawiony banalny przykład użycia tokena TODO: public class Foo { public void Bar() { //TODO implement this method } } Następnie należy otworzyć okno Task List (jesli nie mamy go jeszcze otwartego ;)) z menu górnego: View -> Task List. Po otwarciu okna przechodzimy na zakładkę “Comments” i powinniśmy zobaczyć coś takiego: Nasz nowo dodany komentarz TODO pokazuje się w Task List. Pełen sukces 🙂 Jeśli czujemy potrzebę dodania nowych tokenów możemy zrobić to przechodząc do okna opcji: Tools -> Options -> Enviroment -> Task List. Zobaczymy wtedy takie okno: W polu “Name” należy wpisać nazwę nowego tokena, następnie kliknąć do przycisk “Add” i gotowe 😉 Task List możemy wykorzystać, więc do tak oczywistych zastosowań jak informowanie o kawałkach kodu, które nie są jeszcze do końca zaimplementowane albo o zadaniach, które trzeba wykonać.