Ahoj,
co konkretne pod SOA myslis? COM+ (DCOM) alebo SOAP (1.1 / WCF)? S DCOMami na .Nete skusenosti velke nemam (skor Delphi), ale SOAP (ASMX aj SVC) mame implementovany v niekolkych systemoch a mozem len potvrdit, ze pouzivanie neserializovatelneho typu v metode mozne je, samozrjeme ak tento typ nie je sucastou interface (vstupny argument / vystupny parameter).
Taktiez si treba davat pozor, aby sa v publikovanej triede (ktora moze byt vystupom) nenachadzal v jej interface (ako napr. jej clen). Vtedy sa da vyvolat atribut [XmlIgnore, SoapIgnore] a trieda bude serializovatelna.
Prosim, vyextrahuj demo priklad (interface / implementacia) - celkom by ma zaujimalo co sa v tvojom pripade deje - kedze nastava cas prerobenia nasich SOAP 1.1 do WCF... ci tu nie je nieco - o com by som vediet :)
Dakujem.
Příspěvky odeslané z IP adresy 88.212.35.–
To Hanka :
A google co na to?
http://www.google.sk/#hl=sk&source=hp&q=Armstrongova+%C4%8D%C3%ADsla&meta=&aq=f&aqi=&aql=&oq=&gs_rfai=&fp=56707111ce91a665
To Martin66 :
Ak obrazok negenerujes v run-time, ale mas ho v ASPX, tak z neho urob server-side component <asp:Image id="ImageObrazok" runat="server" ... />
Potom mu inicializuj z requestu URL, napr. v OnLoad ImageObrazok:
string obrazokNazov = Request["id"] ?? "Empty.png";
ImageMojObrazok.ImageUrl = Page.ResolveClientUrl("~/Images/" + obrazokNazov);
No, nie som si isty, ci toto ma M$ odmakane (takze problem popisem z mojho pohladu - teda neviem povedat, ci ten tvoj je nespravny), ale tvoj priklad (s backgroundowrkerom) vyzera skor okopceny z desktopovej aplikacie. Background worker vytvori separovany tread, co nie je problem si "napisat" aj sam, na webe mas iny problem - vytvorit callback na klienta.
Web je klient-server architektura. Upload suboru na server, znamena, ze z klienta zacnes citat data, ktore postupne (v JEDNOM requeste) posielas na server. Ty chces ale zo servera na klienta vratit stav, napr. ze uz je skopirovanych 10%. Co sa teda stane, klient ma otvoreny request a prijma response pred ukoncenim requestu? Kvoli tomu musis odmakat posielanie suboru a prijimanie "stavov" oddelene. Tu je starsi priklad, akoby to mohlo fungovat:
http://www.brettle.com/Demo.aspx
Typickym prikladom pre web je napr. synchronizacia B2B aplikacii, ktora vytazuje server. Klient v takom pripade nevidi nic, len ze sa stranka "natahuje" - to su vlastne time-outy, v ktorych sa serveru opyta, "ci uz neskoncil" s renderovanim stranky. Ak takuto fciu hodi do threadu (server thread), klient moze dostavat ciastkovy stav (nie ci uz neskoncil, ale progress stav - kde sa prave nachadza). Na to sa pouzije napr. javascriptove volanie v cykle o "odpoved" (klient thread) - toto ma vyhodu, klient takto nedostane time-out napr. z proxy servera (nie len session time-out z aplikacneho servera).
Ak vlastne pochopis tuto filozofiu - potom mozes zacat kombinovat tuto techniku napr. s Ajaxom:
http://geekswithblogs.net/rashid/archive/2007/08/01/Create-An-Ajax-Style-File-Upload.aspx
Toto funguje v podstate podobne - na strane klienta sa zavesi "thread" ktory sa asynchronne pyta servera, v akom je stave a podla toho vykresluje progressbar (neskusal som to, neviem ci funguje).
To JiriVavru :
Teraz som zmateny :) Chces do stringu nacitat vystup zo SP? A ten vystup je co, OUTPUT parameter, alebo QUERY?
1. Ak vracias query, kludne mozes presmerovat vystup do readera (a chodi v cykle po vetach).
2. Ak je to vystupny parameter, tak ho vracias ako RETURN alebo INPUTOUTPUT parameter?
RETURN ---> command.Parameters.Add("RETURN_VALUE", /*???*/SqlDbType.BigInt).Direction = ParameterDirection.ReturnValue;
OUTPUT ---> command.Parameters.Add("@R_SurveyID", SqlDbType.Int).Direction = ParameterDirection.Output;
...
command..ExecuteNonQuery();
...
NAVRAT V PARM ---> int mojeCislo = (int)context.Command.Parameters["RETURN_VALUE"].Value;
Nie je velmi standardne pouzivat nie DB objekty na pracu s DB - v podstate to je cesta do pekla, je vhodnejsie sa zoznamit s DB. Akokolvek toto je jedna z moznosti:
listBox1.Items.Clear();
string connectinString = GetConnections().ConnectionStrings[comboBoxConnections.SelectedItem.ToString()].ConnectionString;
using (SqlConnection connection = new SqlConnection(connectinString))
{
connection.Open();
using (SqlCommand command = new SqlCommand("SELECT * FROM SourceOfData", connection))
{
using (SqlDataReader reader = command.ExecuteReader(System.Data.CommandBehavior.CloseConnection))
{
while (reader.Read())
listBox1.Items.Add(reader.GetString(1));
} // using
} // using
} // using
No asi by bolo vhodne uviest instanciou coho je tvoja tabulka. predpokladam, ze DS bude DataSource takze asi DataTable. Ak je tomu tak, tak si najprv rozoberme tvoj prikad: Tables je pole tabuliek, source ich moze mat viac, takze spravne najprv vyhladas "svoju" tabulku. Potom chcel stlpec, co by nemuselo byt od veci, ale stpec moze (ale nemusi) obsahovat jeden zaznam, dokonca sa ocakava, ze ich bude viacej. Takto si si vlastne vyselektoval N hodnot toho stlpca - ToString() nevie ktoru hodnotu ocakvas, kedze vracia prave jeden string, nie N, takze programator nepretazil ToString().
Ako na to? Treba obratit logiku. Najprv si vyhladaj RIADOK a potom sa pozri na hodnotu stlpcva daneho riadku, napr.:
string hodnota = (string)dataSource.Rows[CISLO RIADKU][NAZOV STLPCA];
Ak potrebujes odchytit kliknutie v komponente, znova si otvor TControl. Ako sme sa uz dozvedeli event OnClick vlastne je handler pre kliknutie z aplikacie. Ak si das v kode vyhladat toto: OnClick(Self) tam sa vola tvoj event, ked je definovany Assigned(FOnClick).
Ako vidis, je to metoda procedure TControl.Click; ked sa pozriet na jej interface CTRL+SHIFT+Sipka hore, zistis ze je dynamicka (to je v podstate ako virtual - nemusis to riesit v tomto stadiu skusenosti) - ale dolezity je fakt, ze ju vieme prepisat! Kto a ako ju vola nas opat nemusi zaujimat (staci nam cista logika na objavovanie tajov programovania, zvysok pride sam).
Vratime sa spat do svojho komponenty a overrideneme Paint metodu, kde zavolame invalidate. To sposobi, ze sa komponent "prekresli". Ucinok odchytenia eventu mozeme vyskusat tak, ze budeme generovat nahodne farbu ciary - podla toho si upravime OnPaint, konkretne riadok anvas.Pen.Color := nastavime na nahodnu farbu.
Teraz ked si spustis aplikaciu, tak pri kliknuti sa ti zacnu menit ciary - teda ich farba. Ak si vsak nechal v metode Click LEN invalidate, tak ako si mozes vsimnut, uz sa ti prestal spustat povodny event overridovany na formulari. To je preto, ze sme Click prekryli uplne novym telom a tak sa povodne nikdy uz nevykonalo. Aby sme to zabezpecili, musime ho zavolat (OOP) cez inherited metodu.
Vysledny kod moze vyzerat takto:
unit Unit2;
interface
uses
Controls, Graphics;
type
// *****************************************************************************
// *** TMojControl *************************************************************
// *****************************************************************************
TMojControl = class(TGraphicControl)
protected
procedure Paint; override;
procedure Click; override;
function GetLineColor: TColor;
published
property OnClick;
end; // MojLabel
implementation
uses
Windows;
// *****************************************************************************
// *** TMojControl *************************************************************
// *****************************************************************************
function TMojControl.GetLineColor: TColor;
begin
Result := TColor(Random(255));
end;
// *****************************************************************************
procedure TMojControl.Click;
begin
Invalidate; // Vykreslime objekt este raz
inherited Click; // Zavolame povodnu udalost, ktora vola event handler
end;
// *****************************************************************************
procedure TMojControl.Paint;
// ---------------------------------------------------------------------------
procedure LineXY(Canvas: TCanvas; X1, Y1, X2, Y2: Integer);
begin
if Assigned(Canvas) then
begin
with Canvas do
begin
MoveTo(X1, Y1);
LineTo(X2, Y2);
end; // WITH
end; // IF
end;
// ---------------------------------------------------------------------------
begin
Canvas.Pen.Color := GetLineColor; // Popytame si nahodnu farbu
// Nakreslime krizik
LineXY(Canvas, 0, 0, Width, Height - 1);
LineXY(Canvas, 0, Height - 1, Width, 0);
end;
// *****************************************************************************
// *** TMojControl *************************************************************
// *****************************************************************************
initialization
Randomize; // Aktivujeme generator nahodnych cisel
end.
Hore som ti popisal vseobecny postup tvordby eventov (ked potrebujes chytat message / signaly) z GUI.
Oprasil som moje starucke Delphi 7 uz zabudnute kdesy v Program Files ;) a vlastne som zistil, ze je to este jednoduchsie - ak chces konkretny klik.
Neviem od coho mas odvodeny tvoj kontrol a tak sa velmi tazko radi - pretoze neviem na co to chces pouzit, imho, desktopovo som uz nemyslel roky, ale ukazem ti v rychlosti ako na to:
1. Vytvor si triedu TMojControl a odvod ju od TPanel (daj do usingu ExtCtrls) - predpokladam, ze robime nad VCL (TMojControl = class(TPanel)).
2. Neviem ako nieco funguje, takze drzim CTRL a kliknem na TPanel. Uvidim, ze definuje v published event OnClick, ktory hladam. Definicia ktoru tam vidis je len vytiahnutim interface z predka - teda kod nedefinuje trieda TPanel ale je to zdedene. TPanel to len "publikuje". To je dobry zvyk vytvarat komponenty takto, pretoze ak niekto by chcel pouzit len cast z nasho komponentu, rozsirit ho, ale OnClick nie je pre neho relevantny, tak ho proste nebude publikovat.
Takze drzim CTRL a doklikam sa az ku definicii OnClick ktora je priamo na TComponent triede. Je definovana ako protected - tj. odvodena trieda tuto property vidi, ale instancia uz nie (preto najvrchnejsi panel vytiahol definiciu do published). Rozdiel medzi public a published je v dizajneri. Ten totiz enumeruje len published property (to co vidis v object inspectore).
Ako to funguje (ten click) sa mozes pozriet na komponente TComponent (popisal som to vyssie). Kedze chces vyuzit prave CLICK ktory uz bol definovane, tak velmi sa tomu rozumiet nemusis - pretoze uz to za teba odmakali v Borlande.
3. Takze viem, ze vsetky komponenty odvodene od TComponent uz maju odmakany klik, ja len potrebujem vytiahnut tu funkcnost vonku. Tak pre nas priklad si vytvorim komponent, ktory ma canvas - aby som vedel nieco namalovat - neviem co robi tvoj komponent, ale je to jedno - moj zobrazi krizik:
TMojControl = class(TGraphicControl)
protected
procedure Paint; override;
published
property OnClick;
end; // MojLabel
Ako si mozes vsimnut overriduje Paint metodu - to som vykradol z triedy TPanel (TCustomPanel) ked som hladal, ako sa vlastne vykresluje. Ja pouzijem len Canvas na ktory mozem malovat, z toho dovodu neodvadzam triedu od TCustomPanel ale priamo od TGraphicControl pretoze vlastnosti TPanelu vlastne nepotrebujem.
Ako si tiez mozes vsimnut vytahujem do published OnClick presne tak, ako to urobili s TPanelom.
Takto moze vyzerat telo Paint:
procedure TMojControl.Paint;
// ---------------------------------------------------------------------------
procedure LineXY(Canvas: TCanvas; X1, Y1, X2, Y2: Integer);
begin
if Assigned(Canvas) then
begin
with Canvas do
begin
MoveTo(X1, Y1);
LineTo(X2, Y2);
end; // WITH
end; // IF
end;
// ---------------------------------------------------------------------------
begin
Canvas.Pen.Color := clBlack;
LineXY(Canvas, 0, 0, Width, Height - 1);
LineXY(Canvas, 0, Height - 1, Width, 0);
end;
4. Idem vyskusat co som urobil. Tento komponent by si mal presunut do vlsatneho suboru, ktory bude sucastou nejakeho BPLka, ktore si naimportujes do Delphi, pridas na paletu a uvidis svoj komponent. Ale to uz asi vies.
Mne sa to robit neche (ani si to uz poriadne nepamatam) a tak si ho vytvorim v run-time. Urobim si novu aplikaciu, pridam odkaz na moj komponent v usingu, subor zaradim do projektu.
Vo FormCreate vytovrim moj komponent:
procedure TForm1.FormCreate(Sender: TObject);
begin
with TMojControl.Create(Self) do
begin
Top := 20;
Left := 30;
Width := 100;
Height := 50;
OnClick := Kliknutie;
Parent := Self;
end; // with
end;
Po prelozeni ti zahlasi chybu, ze neexistuje Kliknutie metoda, tak ju pridam do definicii triedy (je to event, takze podla logiky Delphi 7 by mala byt definovana priamo pod FormCreate (bez private / public / protected).
Ta metoda moze vyzerat takto:
procedure TForm1.Kliknutie(Sender: TObject);
begin
ShowMessage('Kukuk');
end;
Teraz ked niekto klikne na moj "krizik" tak sa mu zobrazi hlasenie.
Niekedy na strednej skole som pisal clanky (teraz sa ku nim nechcem velmi hlasit ;) ), ale myslim, ze som tam to poriesil:
http://www.accendo.sk/Clanky/CiselneSustavy.html
http://www.accendo.sk/Clanky/CiselneSustavy_II.html
Asi by bolo lepsie si urobit CheckBox list komponent, ak nieco take neexistuje (nepamtam sa), ale tvojim rychlim riesenim by bolo, ak by si tie checkboxy umiestnil na nejaky panel. Potom na tomto panely by si prechadzal jeho Controls v cykle asi takto:
for Index := 0 to Pred(PanelMojeCheckboxy.Controls.Count) do
begin
if PanelMojeCheckboxy.Controls[Index] is TCheckBox then
??? := TCheckBox(PanelMojeCheckboxy.Controls[Index]).ItemIndex;
end; // for
Mozes si na to urobit fciu, ktora ti to vrati - posles jej len panel parametrom. Ta fcia je dobry napad, pretoze mozno budes potrebovat checkboxy hladat aj na inych paneloch, ktore su umiestnene na tom panely, vtedy ju budes musiet trocha modifikovat, aby si to volal v rekurzii, napr.:
if PanelMojeCheckboxy.Controls[Index] is TCheckBox then
??? := TCheckBox(PanelMojeCheckboxy.Controls[Index]).ItemIndex
else if PanelMojeCheckboxy.Controls[Index] is TWinControl then
NazovFciew(PanelMojeCheckboxy.Controls[Index]); // ???
To sa vola event. Ak mas vlastny komponent, zalezi od coho bol odvodeny. Na odchytavanie udalosti existujuceho komponentu vies pouzit metody, ktore overridnes - ak je to komponent, ktory si urobil odvodenim od nejakeho abstraktneho komponentu, musis si click odchytit cez message - pozri sa, ako sa to robi v inych kompontenotch, ved Delphi je distribuovane (ked sa dobre pamatam) so zdrojakmi.
Samotny event handler si urobis tak, ze si zadefinujes (alebo pouzijes existujuci) typ TMojEvent = function(Sender: ???, Args ???): Boolean;
a tento typ pouzijes ako published property: property OnMojEvent: TMojEvent read FOnMojEvent write FOnMojEvent;
potom zistis, ci komponent ma definovany event na mieste, kde ho chces volat if Assigned(OnMojEvent) then OnMojEvent(Self, ???);
Toto budes volat tam, kde si odchytis message. Delphi som uz nejaky ten rok nevidel, ale napr. KeyDown chytis tak, ze si zadefinujes napr. procedure CNKeyDown(var Message: TWMKeyDown); message CN_KEYDOWN;
telo fcie moze byt take:
procedure TMojKomponent.CNKeyDown(var Message: TWMKeyDown);
begin
if Message.CharCode = VK_RETURN then
???
inherited;
end;
ak das do vnutra volanie toho eventu (ale pred tym zisti, ci nie je nil) tak tvoj komponent ked dostane informaciu, ze na nom bola stlacena klavesa, zavola tvoj event.