Zanimljivosti
Dubravko Kukec
Google Adds
Anketa
Zante li što je to MVC?



GoogleAdds
Blog
utorak, siječanj 12, 2010
ASP.NET MVC 2 RC (framework za razvoj web aplikacija kojemu su prednosti lako testiranje i održavanje, a temelji se na model-view-controller patternu) dostupan je na slijedećoj adresi:

http://www.microsoft.com/downloads/details.aspx?FamilyID=3b537c55-0948-4e6a-bf8c-aa1a78878da0&displaylang=en
dkukec @ 21:23 |Komentiraj | Komentari: 0
četvrtak, kolovoz 13, 2009
Zanimljiva vijest: Microsoft je odlučio preseliti svoju Azure cloud computing platformu iz datacentra u državi Washington (Quincy) u drugi datacentar u državi Texas (San Antonio) iz vrlo jednostavnog razloga. Porez. Dakle, porez je niži u Teksasu (više detalja). Amazon, Oracle, Google i Yahoo su već odustali od iste države iz istog razloga. Možda bi netko i u Hrvatskoj trebao razmišljati o "opasnostima" trenutne porezne politike (al nećemo o politici na ovom blogu).
dkukec @ 14:08 |Komentiraj | Komentari: 0
srijeda, srpanj 22, 2009
Microsoft je objavio cijene za Azure platformu. Detalji na Pricing & Licensing Overview stranici.
dkukec @ 15:25 |Komentiraj | Komentari: 0
petak, srpanj 10, 2009
dkukec @ 11:06 |Komentiraj | Komentari: 0
petak, srpanj 3, 2009
MICROSOFT je u svojoj novoj reklamnoj kampanji iskoristio protiv konkurencije njihovo vlastito oružje. Naime, konkurenti po njima često pljuju i nazivaju njihove proizvode smećem, a Microsoft je u reklami za novi internetski preglednik Internet Explorer 8 otišao čak i korak dalje te šokirao korisnike reklamom s povraćanjem.

Microsoft je reklamu O. M. G. I. G. P. (Oh My God I`m Gonna Puke!) ubrzo uklonio sa svojih stranica zbog pritužbi korisnika, ali prekasno - proširila se internetskim servisima za razmjenu video klipova.

dkukec @ 14:32 |Komentiraj | Komentari: 0
Ako uzmemo mpr. Northwind i napišemo upit "SELECT CategoryId, ProductName FROM Northwind..Products;", dobijemo slijedeći rezultat:

CategoryId ProductName 

 1 Chai
1 Chang
...
2 Aniseed Syrup
2 Chef Anton's Cajun Seasoning
...
...
8 Spegesild

(77 row(s) affected)


Kako napraviti upit da nam se vrijednosti nekoliko redaka "vrate" kao jedan string, konkretnije da dobijemo ovaj rezultat:

CategoryId Product List 

1 Chai, Chang, Chartreuse verte, Côte de Blaye, ...
2 Aniseed Syrup, Chef Anton's Cajun Seasoning, ...
3 Chocolade, Gumbär Gummibärchen, Maxilaku, ...
4 Camembert Pierrot, Flotemysost, Geitost, Gorgonzola Telino, ...
5 Filo Mix, Gnocchi di nonna Alice, Gustaf's Knäckebröd, ...
6 Alice Mutton, Mishi Kobe Niku, Pâté chinois, ...
7 Longlife Tofu, Manjimup Dried Apples, Rössle Sauerkraut, ...
8 Boston Crab Meat, Carnarvon Tigers, Escargots de Bourgogne, ...

(8 row(s) affected)

Dakle, da za pojedinu kategoriju dobijemo string koji sadrži listu proizvoda te kategorije, a ne da svaki proizvod u posebnom retku. Postoji nekoliko rješenja (npr. korištenjem cursora, rekurzije, korištenjem CLR-a, itd.), no osobno mi se svidio jedan "jednostavan" način korištenjem XML metoda. Dakle, da dobijemo prije željeni rezultat, upit bi trebao izgledati poput ovoga:

    SELECT p1.CategoryId,
          ( SELECT ProductName + ','
              FROM Northwind.dbo.Products p2
             WHERE p2.CategoryId = p1.CategoryId
             ORDER BY ProductName
               FOR XML PATH('') ) AS Products
      FROM Northwind.dbo.Products p1
     GROUP BY CategoryId ;


Za kraj, preporučio bih slijedeći članak koji se bavi ovom tematikom: http://www.projectdmx.com/tsql/rowconcatenate.aspx

dkukec @ 08:14 |Komentiraj | Komentari: 0
utorak, lipanj 9, 2009
Naredba (Commands) poput Cut, Copy ili Paste predstavljaju određene zadatke. WPF uvodi novi tip objekata koji predstavlja naredbe, te omogućava centraliziranu arhitekturu zadataka. Drugim rječima, bilo koji broj kontrola može se pridružiti određenoj naredbi koja izvršava određeni kod.

Arhitektura naredbi sastoji se od četiri osnovna dijela:
- Command object - predstavlja zadatak
- Command source - kontrola ili događaj koji poziva naredbu
- Command handler - metoda koja se izvršava kod poziva naredbe
- Command binding - objekt koji se koristi za praćenje koje naredbe su povezane sa kojim elementima

Postoje nekoliko predefiniranih naredbi koje se mogu koristiti. To su statični objekti kao svojstva pet statičnih klasa:
- ApplicationCommands
- ComponentCommands
- EditingCommands
- MediaCommands
- NavigationCommands

Kako pozvati određenu naredbu? Većina WPF kontrola implementiraju ICommandSource interface koje implementira Command svojstvo. Postavljanjem vrijednosti tom svojstvu, definirana naredba se automatski izvršava kad se npr. klikne na kontrolu. Primjer:

<Button Command="ApplicationCommands.Find" ...>Button</Button>

Osim toga, može se reagirati i na pokret mišem ili pritiske na tipkovnicu. Pridruživanje određenih "pokreta" određenoj naredbi vrši se kao u slijedećem primjeru:

ApplicationCommands.Find.InputGestures.Add(new MouseGesture(MouseAction.Left.Click, ModifierKeys.Control));

Posljednji način pozivanja određene naredbe je kroz kod:

ApplicationCommands.Find.Execute(aParameter, TargetControl);

Slijedeći korak je definiranje handler-a i pridruživanje handler-a određenoj naredbi:

private void myCommandHandler(object sender, ExecuteRoutedEventArgs e)
{
   //...
   e.Handled = true;
}

CommandBinding aBinding = new CommandBinding();
aBinding.Command = ApplicationCommands.Find;
aBinding.Executed += new ExecutedRoutedEventHandler(myCommandHandler);
this.CommandBindings.Add(aBinding);

ili direktno preko XAML-a:

<Window.CommandBindings>
   <CommandBinding Command="ApplicationCommands.Find" Executed="myCommandHandler" />
</Window.CommandBindings>

I to je to...

dkukec @ 12:54 |Komentiraj | Komentari: 0
utorak, lipanj 2, 2009
Potoji način kako da pokrenemo dva "duža" upita istovremeno, a da rezultat upita nastavimo obrađivati čim je bilo koji od ta dva upita izvršen. Dakle, ako je prvo prvi upit završio, obradimo njega, a ako je prvo završio drugi upit, on ima prednost u daljnjoj obradi. Kako to napraviti? Slijedeći "kod snipet" daje uvid u to:

private void GetData()
{
   IAsyncResult[] iasyncresults = new IAsyncResult[2];
   WaitHandle[] waitHandles = new WaitHandle[2];

   string firstConnectionString = "Server=serverName;Database=databaseName;Trusted_Connection=true;Asynchronous Processing = true";
   SqlConnection firstConnection = new SqlConnection(firstConnectionString);
   firstConnection.Open();
   SqlCommand firstCommand = new SqlCommand("WAITFOR DELAY '00:00:20'; SELECT * FROM Table1", firstConnection);
   iasyncresults[0] = firstCommand.BeginExecuteReader(null, firstCommand, CommandBehavior.CloseConnection);
   waitHandles[0] = iasyncresults[0].AsyncWaitHandle;

   string secondConnectionString = "Server=serverName;Database=databaseName;Trusted_Connection=true;Asynchronous Processing=true";
   SqlConnection secondConnection = new SqlConnection(secondConnectionString);
   secondConnection.Open();
   SqlCommand secondCommand = new SqlCommand("WAITFOR DELAY '00:00:05'; SELECT * FROM Table2", secondConnection);
   iasyncresults[1] = secondCommand.BeginExecuteReader(null, secondCommand, CommandBehavior.CloseConnection);
   waitHandles[1] = iasyncresults[1].AsyncWaitHandle;

   for (int i = 0; i < waitHandles.Length; i++)
   {
      int index = WaitHandle.WaitAny(waitHandles);
      SqlCommand cmd = (SqlCommand)iasyncresults[index].AsyncState;

      // ovisno o vrijednosti indexa znamo koji upit je završio
      switch (index)
      {
         case 0:
            using (SqlDataReader reader = cmd.EndExecuteReader(iasyncresults[index]))
            {
               while (reader.Read())
               {
                   //... 
               }
            }
           break;
        case 1:
           using (SqlDataReader reader = cmd.EndExecuteReader(iasyncresults[index])) 
           {
               while (reader.Read())
              {
                    //...
               }
             }
           break; 
        }
     }

   firstConnection.Close();
   secondConnection.Close();
}
dkukec @ 09:44 |Komentiraj | Komentari: 0
petak, svibanj 29, 2009
U WPF aplikacijama korisničko sučelje se sastoji od hijerarhije kontrola, jedna kontrola sadrži više kontrola. Primjer
je Window objekt koji može sadržavati Grid objekt koji opet sadrži nekoliko kontrola itd. Routed event arhitektura se
temelji na tome i omogućava da se event jedne kontrole može "izazvati" od strane druge kontrole u hijerarhiji kontrola.
Npr., kad korisnik klikne na gumb u Toolbar-u, taj event se može izazvati od strane Button-a, ToolBar-a, Grid-a ili
Window-a.

Postoje tri tipa Routed evenata.

Direct Events su slični standardnim .NET eventima i mogu se izazvati samo od kontrole iz koje proizlaze. Primjer je
MouseLeave event koji određena kontrola izazove ali i nudi handler za taj event.

Bubbling Events su eventi koje izazove određena kontrola i zatim je taj event izazvan od svih nadređenih kontrola u
hijerarhiji, nazvano visual tree. Primjer je MouseDown event koji se izazove kad se klikne na labelu. U tom slučaju prvo
labela izazove event, zatim noe. FlowPane, a na kraju Window. Handler za taj event se može "razviti" na bilo kojoj ili
na svim razinama event procesa.

Tunneling Events su suprotnost Bubbling eventima i njihov smjer je od vršnog elementa u hijerarhiji kontrola pa do
"najniže" kontrole u hijerarhiji. Primjer je PreviewMouseDown event. Takav način omogućava da se uhvate i obrade eventi
prije nego se obrade od strane određene kontrole. Svi takvi eventi u .NET-u počinju sa Preview* i imaju komplementarni
Bubbling event (npr. PreviewMouseDown i MouseDown), a važno je da međusobno dijele instancu event argumenata.


RoutedEventArgs sadrže slijedeća svojstva: Handled, OriginalSource, RoutedEvent, Source.

EventManager klasa omogućava upravljanje eventima u aplikaciji. Pomoću EventManager.RegisterRoutedEvent mogu se
registrirati novi routed eventi. Također, pomouću EventManager.RegisterClassHandler mogu se kreirati event handleri na
razini klase.

Application objekt ima nekoliko evenata koji se mogu obraditi u različitim trenucima životnog ciklusa aplikacije.
Application level eventi mogu se obraditi u kodu Application objekta. Npr. u code behind App.xaml stranice dodaje se
slijedeći event:

void App_Startup(object sender, StartupEventArgs e)
{
    //Handle event
}

App.xaml je mjesto gdje se event poziva:

<Application x:Class="WpfApplication1.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    StartupUri="Window1.xaml" Startup="App_Startup">
    <Application.Resources>

    </Application.Resources>
</Application>
dkukec @ 10:33 |Komentiraj | Komentari: 0
četvrtak, svibanj 28, 2009
Ako u aplikaciji koristimo metode koje se dugo izvršavaju, dobra praksa je te metode pokrenuti u novoj dretvi (Thread). Slijedi primjer kako to napraviti. Potrebna nam se XAML stranica sa dvije labele, progressbar-om, te dva gumba, a code behind te stranice je slijedeći:

    public partial class BGWorker : Page
    {
        BackgroundWorker aWorker = new BackgroundWorker();


        public BGWorker()
        {
            InitializeComponent();
            //omogućimo Cancel i "progres" funkcionalnost
            aWorker.WorkerSupportsCancellation = true;
            aWorker.WorkerReportsProgress = true;


            //pretplatimo se na evente
            aWorker.DoWork += new DoWorkEventHandler(aWorker_DoWork);
            aWorker.ProgressChanged += new ProgressChangedEventHandler(aWorker_ProgressChanged);
            aWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(aWorker_RunWorkerCompleted);
        }


        #region BackgroundWorker Events
       
        void aWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            for (int i = 0; i <= 10; i++)
            {
                MyLongMethod();
                aWorker.ReportProgress(i * 10);
                if (aWorker.CancellationPending)
                {
                    e.Cancel = true;
                    return;
                }
                UpdateLabelDelegate update = new UpdateLabelDelegate(UpdateLabel);
                label1.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, update, i);
            }
        }


        void aWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            //potrebno je koristiti Dispatcher kako bi se iz thread-a sigurno izvršio kod na objektima UI-a
            //iz tog razloga koriste se delegati
            UpdateProgressDelegate update = new UpdateProgressDelegate(UpdateProgress);
            progressBar1.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, update, e.ProgressPercentage);
        }


        void aWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (!(e.Cancelled))
                label2.Content = "Run Completed!";
            else
                label2.Content = "Run Cancelled!";
        }


        #endregion

        #region Metoda koja se dugo izvršava

        private void MyLongMethod()
        {
            Thread.Sleep(1000);
        }


        #endregion

        #region delegates

        private delegate void UpdateLabelDelegate(int i);
        private void UpdateLabel(int i)
        {
            label1.Content = "Cycle: " + i.ToString();
        }


        private delegate void UpdateProgressDelegate(int i);
        private void UpdateProgress(int i)
        {
            progressBar1.Value = i;
        }


        #endregion

        #region klikovi na gumbe

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            aWorker.RunWorkerAsync();
        }


        private void button2_Click(object sender, RoutedEventArgs e)
        {
            aWorker.CancelAsync();
        }


        #endregion
    }

Naravno, potrebno je dodati i slijedeće:

using System.ComponentModel;
using System.Threading;

dkukec @ 10:27 |Komentiraj | Komentari: 0
MSN