Hõbevalge nagu Silverlight :)

h6bevalge kolib, sest wordpress.com lihtsalt ei võimalda kõike seda mida mul vaja on. Seega organiseerin ma blogi aadressile http://h6bevalge.riiul.com, siis saan kujundada ta täpselt selliseks nagu ma tahan, põletada feedi läbi feedburneri ning mis kõige olulisem, lisada Silverlight sisu otse postituste sisse :)

Seega uus aadress: http://h6bevalge.riiul.com ning uus feed: http://feeds2.feedburner.com/h6bevalge

Kõik sisu ning kommentaarid on ümbertõstetud ning see lehekülg siin jääb üles veel 1 kuuks, selle ajaga ma loodan jõuavad siia sattuda kõik minu lugejad ning end uue aadressiga kurssi viia. Edaspidi lehekülg sulgub, sest mina näiteks ei kannata seda, kui ma netist midagi otsin ja siis koperdan mingi kolinud blogi otsa. Sisu olgu ühes kohas. Küll otsingumootorid saavad aru, et me kolisime :)

Küsimus laiale ringile. Kes pakub Eestis asp.net hostingut? Eriti hea oleks muidugi .net 3.5-ga … Oskate midagi soovitada?

Sildid:

Olukord: Tõstsin oma projekti teise arvutisse ning pärast seda ma teste enam jooksutada ei saanud

Error: 

The Web request ‘http://localhost:1234/midagi/midagi’ completed successfully without running the test. This can occur when configuring the Web application for testing fails (an ASP.NET server error occurs when processing the request), or when no ASP.NET page is executed (the URL may point to an HTML page, a Web service, or a directory listing). Running tests in ASP.NET requires the URL to resolve to an ASP.NET page and for the page to execute properly up to the Load event. The response from the request is stored in the file ‘WebRequestResponse_CreateProviderTest.html’ with the test results; typically this file can be opened with a Web browser to view its contents.

Lahendus: Kuna see projekt asus mõlemal arvutil Desktopil ainsa vahega, et kasutajanimi oli teine, siis ma ei pidanud eriti midagi muutma ainult selle nime. 

[AspNetDevelopmentServerHost(“C:\\Users\\Jaana Metsamaa\\Desktop\\Visual Studio 2008\\Projects\MinuProjekt\\

Vot aga kopeerimistöös tekkis viga sisse.

Sest Minu projekt on lahenduse (Solution) nimi mitte selle projekti nimi, mida ma testin. Ehk kui lisada lahenduse nimi, siis töötab :)

 

[AspNetDevelopmentServerHost(“C:\\Users\\Jaana Metsamaa\\Desktop\\Visual Studio 2008\\Projects\MinuProjekt\\Projekt

Kõige muserdavam mure, mis mul Visual Studioga on olnud on see, kui ükskord ma vajutasin F5, et alustada debugimist, sama moodi nagu ma olin seda enne teinud tuhandeid kordi varem aga tol ja kõikidel järgmistel kordadel võttis debugimise alustamine 25-40 sekundit… kohutavalt pikk aeg…  

Millest see tuleneb ja kuidas sellest lahti saada? Lahendus on ebanormaalselt lihtne… isegi kui koodis on ainult 2-3 breakpointi tuleb need eemaldada (mitte lihtsalt eemaldada vaid eemaldada kasutades menüü käsku Delete all breakpoints…) ja see aitab ja pärast järgmist buildi võib kõik breakpoindid tagasi panna.. täielik anomaalia…

Minu vastus ja väike arutelu samal teemal Stackoverflows:

http://stackoverflow.com/questions/442213/vs2008-sp1-pressing-f5-takes-ages-to-start-website#442321

Teate seda Visual Studio akent (logo ja nimed), mida käivitamisel näidatakse… vot selle saab ära jätta ja siis läheb VS vähemasti 2 sekundit kiiremini käima… seda ei ole palju aga samas sekunditest saavad minutid ja minutitest tunnid, nii et pikemas perspektiivis võib see täitsa ära tasuda…

Ilma splash-screen’ita näitamiseks tuleb lisada /nosplash argument

Visual Studio 2008 short-cuti peal paremklikk ja siis modifitseerida target väärtust:

“C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe”  /nosplash

Mõni postitus tagasi andsin nipi, kuidas Silverlight rakendused täisekraanile saada aga on ju veel üks variant täisekraanist – see, kui rakendus täidab kogu veebilehe.

Luues Silverlight rakenduse näeb Page.xaml fail alguses välja umbes selline:

<UserControl x:Class=”h6bevalge.Tips.Autosize.Page”

    xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation” 

    xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml” 

    Width=”400″ Height=”300“>

    <Grid x:Name=”LayoutRoot” Background=”White”>

        <Button x:Name=”button” Content=”Tere!” />

    </Grid>

</UserControl>

Kus Width=”400″ Height=”300″  on rakenduse suurus, et see oleks täpselt nii suur kui on veebilehitseja võib need väärtused täitsa ära kustutada, mis on samaväärne väärtustega Width=”Auto” Height=”Auto”. Iga objekt, mille kõrgus või laius on Auto täidab ära kogu ruumi, mis tal antud on. 
Kasutades Width=”Auto” Height=”Auto” tekib aga rakenduses Expression Blend veidi ebamugavusi – esialgne kujundus läheb täiesti paigast ära, sest objektid ei asu veebilehitsejas  ja seega neil ei ole mingit ruumi antud ning kõike näidatakse 0x0 suurusega… et seda vältida võib paika seada suurused disainiajaks – d:DesignWidth=”640″ d:DesignHeight=”480″ nii on paigutus ka Blendis paigas.

Sain mõni päev tagasi kirja ühelt inimeselt, kes oli näinud minu MIX esitlust ning saanud sellest innustust teha mõned Deep Zoom albumid ja nüüd soovis viia albumid järgmisele tasemele lisades piltide juurde ka selgitavat teksti. Ja tõsi ta on, siia ajaveebi jõuavad ka tellitud teemad… nii, et tellige aga… kui mul vähegi aega ja huvi on, siis genereerin postituse :)

Projekti ettevalmistamine

Kõigepealt loome Deep Zoom albumi kasutades rakendust Deep Zoom Composer ning paneme piltidele külge kirjeldused ehk tagid. Seda saab teha Compose sammul valides sammu ning sisestades kirjelduse tag kastikesse.

tagimine

Järgnevalt tuleb see album eksportida Silverlight projektina, kusjuures eksportimisel on oluline pildid eksportida kollektsiooni (Collection), mitte kompositsioonina (Composition). Teise variandiga ekrporditakse vaid üks pilt, esimesega aga kõik pildid eraldi ning seega jääb meil ligipääs igale pildile ning tema metadatale.

image

Avades selle Silverlight projekti näeme sellist pilti. Sellest projektipuust huvitavad meid sel korral failid Page.xaml, Page.xaml.cs ning Metadata.xml, kus asuvad need meie kirjutatud kirjeldused.

image Kõigepealt vaatame Page.xaml faili ning lisame sinna tekstikasti, kus piltide kirjeldusi näidata.

Lõpptulemus võiks olla näiteks selline ja siin element MultiScaleImage x:Name=”msi” on Deep Zoom album.

<UserControl x:Class="DeepZoomProject.Page"
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
 Width="Auto" Height="Auto" >
    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.RowDefinitions>
            <RowDefinition Height="0.95*"/>
            <RowDefinition Height="0.05*"/>
        </Grid.RowDefinitions>
        <Border Grid.Row="0" BorderBrush="#FF727272" 
                BorderThickness="1,1,1,1">
            <MultiScaleImage x:Name="msi"/>
        </Border>
        <TextBlock x:Name="taginfo" Text="Siia tuleb pildi info." 
                   Grid.Row="1" TextWrapping="Wrap" 
                   HorizontalAlignment="Stretch" 
                   FontWeight="Bold" 
                   FontFamily="Portable User Interface"/>
    </Grid>
</UserControl>

See, et sinna loodud tekstikasti näidataks iga pildi tag väärtust koosneb kolmest sammust:

  1. Kõigepealt on meil vaja teada, milline pilt fookuses on.
  2. Siis on vaja laadida Metadata.xml fail, sest seal on kirjas iga piltide metainfo.
  3. Kui me teame, milline pilt on fookuses ja Metadata.xml fail on ka laetud, siis otsime sealt LINQ abil õige tag väärtuse välja.

Milline pilt on fookuses?

Miskipärast on nii, et Silverlight koordinaadid ja DeepZoom rakenduse koordinaadid ei kattu ja seepärast on hetkel fookuses oleva pildi leidmine üks arvutamine ja teisendamine. Samas ratast me leiutama ei pea, sest veebist leiab mitmeid ja mitmeid erinevaid viise kuidas seda arvutada.

Üks arvutusviis on järgnev:

Võttes argumendiks Deep Zoom pildi (MultiScaleImage) ning hiire asukoha, käime läbi kõik alampildid (MultiScaleSubImage) ning kontrollime, kas hiire asukoht kattub mõne pildi (ViewPort) asukohaga. Enne kui me seda teha saame, peame teisendama näidatava deep zoom ruudu (ViewPort) koordinaadid vastavateks koordinaatideks DeepZoom pildi peal ning need koordinaadid omakorda teisendame koordinaatideks Silverlight rakenduse suhtes. Need viimased koordinaadid on samas mõõtkavas, kui hiire koordinaadid ja seega saame kontrollida, kas hiire koordinaadid asuvad ühe Deep Zoom pildi peal.  Koordinaatide võrdluseks loome ühe ristküliku, mille koordinaadid vastavad pildi koordinaatidele.

using System.Xml.Linq;
using System.IO;
using System.Text;
using System.Xml;

//Põhineb: 
//http://jimlynn.wordpress.com/2008/10/28/silverlight-deep-zoom-collections-and-hit-testing/
bool GetImageTag(MultiScaleImage aMsi, Point p){ 
    bool gotHit = false; 
    for (int i = 0; i < aMsi.SubImages.Count; i++) 
    { 
        MultiScaleSubImage subimage = aMsi.SubImages[i]; 
        
        // DeepZoom pildid on jagatud ruutudeks 
        // järgnev on hetkel kontrollitava ruudu vasaku ülemise nurga koordinaat. 
// Seda hetkel näidatava pildi suhtes,
        // mitte Silverlight rakenduse suhtes, 
        // ega ka mitte terve Deep Zoom pildi suhtes. 
Point topLeft = subimage.ViewportOrigin;
        //Võttes arvesse zoom taset, 
//arvutame, kus on selle ruudu vasak ülemine nurk DeepZoom pildi suhtes.
        topLeft.X = -(topLeft.X / subimage.ViewportWidth); 
        topLeft.Y = -(topLeft.Y / subimage.ViewportWidth); 
        // Tekitatava ruudu kõrgus
        double width = 1 / subimage.ViewportWidth;
	
        // Tekitatava ruudu laius
	double height = width / subimage.AspectRatio;

	// Tekitatava ruudu ülejäänud kaks koordinaati
	Point bottomright = new Point(topLeft.X + width, topLeft.Y + height);

	// Meil on olemas ruudu koordinaadid Deep Zoom pildi suhtes,
        // teisendame need Silverlight koordinaatideks
topLeft = aMsi.LogicalToElementPoint(topLeft);
        bottomright = aMsi.LogicalToElementPoint(bottomright); 
        // Kontrollime, kas hiire koordinaadid (p) on meie loodud ruudu sees
        Rect r = new Rect(topLeft, bottomright); 
        if (r.Contains(p)) 
        { 
        gotHit = true;
        // Otsime varem laetud Metadata.xml failist (muutuja metadata)
// õige pildi tag väärtuse ning seame selle tekstikasti väärtuseks.
List<string> tags = (from image in metadata.Descendants("Image") where int.Parse(image.Element("ZOrder").Value) == i + 1 select image.Element("Tag").Value).ToList(); this.taginfo.Text = tags.First().ToString(); } } return gotHit; }

Laeme Metadata.xml-i

Selleks, et me saaks XML failist infot otsida, tuleb see fail kõigepealt rakendusse laadida:

bool metadataLoaded = false;
XDocument metadata = new XDocument();

private void LoadMetadataXML()
{
    WebClient webclient = new WebClient();
webclient.DownloadStringCompleted +=
new DownloadStringCompletedEventHandler(MetadataLoaded); webclient.DownloadStringAsync(
new Uri("GeneratedImages/Metadata.xml",
UriKind.RelativeOrAbsolute)); }

 

Kui fail on laetud, loeme tema sees oleva XML-i muutujasse metadata.

private void MetadataLoaded(object sender, DownloadStringCompletedEventArgs e)
{
    if (e.Error == null)
    {
	string xmlData = e.Result;
		
	MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(xmlData));
	XmlReader reader = XmlReader.Create(ms);
	metadata = XDocument.Load(reader);

       	metadataLoaded = true;
    }
}

XML-i laeme kohe rakenduse laadimisel:

void Page_Loaded(object sender, RoutedEventArgs e)
{
    LoadMetadataXML();
}


Nüüd ei olegi muud üle jäänud, kui hiire liigutamisel see meie GetImageTag meetod välja kutsuda:

this.MouseMove += delegate(object sender, MouseEventArgs e)
{
	GetImageTag(msi, e.GetPosition(this.msi));
	if (mouseButtonPressed)
       	{
		mouseIsDragging = true;
	}
	this.lastMousePos = e.GetPosition(this.msi);
};

Ja ongi valmis, nüüd on meil teada ka lisainfo piltide kohta. Muidugi võiks seda infot kuvada kuidagi palju peenemalt, aga ma mõtlen, et kood võiks siin näidetes võimalikult lihtsaks jääda :)

Leiud

Follow

Get every new post delivered to your Inbox.