Wyświetlanie okien i komunikatów¶
Pokazanie okna z ustawieniem parametrów obiektu¶
Aby pokazać okno BROWSE obiektu WFFA.WFFACOSTINVOICE piszemy kod:
ShowForm("WFFA.WFFACOSTINVOICE","BROWSE");
Jeśli dodatkowo do obiektu chcemy przekazać parametry, robimy to w taki sposób:
Contexts kontekst = new Contexts();
kontekst.Add("_booked","0");
ShowForm("WFFA.WFFACOSTINVOICE","BROWSE",kontekst);
W przekazywanym kontekście można ustawiać zarówno wartości parametrów obiektu biznesowego, jak i wartości pól modelu danych. Przy czym ustawienie wartości parametru, po prostu przypisuje ustawioną wartość do parametru, natomiast ustawienie wartości pola nie przypisuje wartości do tego pola, ale nakłada kontekst na to pole (czyli taki bardziej zaawansowany filtr).
Uwaga!
Warto w obiektach tworzyć metody statyczne stanowiące API biznesowe. Dzięki temu zamiast powyższego wywołania okna z załącznikami elektronicznymi, lepiej napisać taki kod:
WFFA.WFFACOSTINVOICE.ShowInvoices();
Pokazanie okna edycji bieżącego rekordu¶
Aby pokazać domyślne okno edycyjne bieżącego obiektu (okno o symbolu EDIT) dla bieżącego rekordu, piszemy:
ShowRecord();
Aby pokazać okno edycyjne o innym symbolu (np. o symbolu DETAILS) bieżącego obiektu dla bieżącego rekordu, robimy tak:
ShowRecord("","DETAILS");
Aby z poziomu jednego obiektu biznesowego pokazać okno edycyjne innego obiektu, musimy jawnie przekazać kontekst rekordu, jaki chcemy pokazać:
public void EditKlient()
{
Contexts c = new Contexts();
c.Add("REF",this.KLIENT);
ShowRecord("COMMON.KLIENCI","EDIT", c);
}
Zakładanie nowego rekordu¶
Aby założyć nowy rekord pokazując domyślne okno edycyjne bieżącego obiektu, piszemy:
ShowNewRecord();
NEW, a jeśli takiego nie ma, to okno o symbolu EDIT.
Aby założyć nowy rekord pokazując okno edycyjne o innym symbolu (np. DETAILS) bieżącego obiektu, robimy tak:
ShowNewRecord("","DETAILS");
Aby z poziomu jednego obiektu biznesowego wywołać założenie nowego rekordu pokazując okno innego obiektu, inicjując jednocześnie wybrane pola konkretnymi wartościami, postępujemy następująco:
public void NewChildFolder()
{
Contexts c = new Contexts();
c.Add("PARENT",this.REF);
ShowNewRecord("WORKFLOW.WFFOLDER","EDIT", c);
}
Zamykanie bieżącego okna¶
Aby zamknąć bieżące okno programowo wywołujemy na nim metodę:
CloseForm()
true. Oznacza ona, że jeśli okno jest w trybie dodawania rekordu lub edycji, to zostanie zadane pytanie, czy na pewno zamknąć to okno. Można tą metodę wywołać z parametrem false, co spowoduje zamknięcie okna natychmiastowe, bez żadnego pytania.
Pokazanie okna słownika¶
Pojęcie słownikowanie (potocznie: dictowanie) odnosi się do sytuacji, gdy w jakimś polu nie wpisujemy wartości bezpośrednio, ale wybieramy ją z jakiegoś słownika / listy. Np wybieramy typ faktury z listy dostępnych typów faktur, albo klienta z listy klientów. Proces słownikowania niezależnie od tego w jaki sposób jest zaimplementowany składa się z kilku elementów:
- Istnieje pole w modelu danych (lub parametr), którego wartość ma pochodzić ze słownika, a nie jest wpisywana ręcznie. Pole to może tak naprawdę przechowywać inną wartość a wyświetlać inną wartość. Np jeśli na dokumencie (obiekt
NAGFAK) mamy poleNAGFAK.KLIENT, które jest słownikowane obiektemKLIENCI, to poleNAGFAK.KLIENTzawiera numer klienta (poleKLIENCI.REF) a wyświetla symbol klienta (KLIENCI.FSKROT). - Mamy okno w którym edytujemy dane tego rekordu i wchodzimy w edycję pola, które ma być słownikowane.
- Otwieramy okno słownika, które może się ustawić na tym rekordzie, który aktualnie był wybrany.
- Wybieramy nowy rekord ze słownika, co powoduje przypisanie nowej wartości do pola słownikowanego (np. przypisuje się nowy
REFklienta do polaNAGFAK.KLIENT) oraz wyświetlenie w tym polu odpowiedniego skrótu klienta. Jeśli rekord edytowany nie był jeszcze w trybie edycji, to jest automatycznie przełączany w tryb edycji. - Zatwierdzamy zmodyfikowany rekord, gdyż proces słownikowania jedynie modyfikuje wartość pola, ale nie zatwierdza automatycznie zmian w rekordzie.
Od strony definiowania okien oraz pisania kodu, słownikowanie można zrealizować na kilka sposobów, które zostały opisane niżej.
Słownikowanie w pełni automatyczne¶
Aby słownikowanie zadziałało w pełni automatyczne słownikowanie, musi być spełnionych kilka warunków:
- pole modelu danych lub parametr musi miec zdefiniowaną relację do słownika
- pole zostanie umieszczone w oknie, łącznie ze wskazaniem pola z obiektu biznesowego słownika, które zostanie wyświetlone w tym miejscu (pole o etykiecie: "a konkretnie ze słownika")
- sposób edycji pola to: EDIT, COMBOBOX, DROPDOWN, CHECKCOMBOBOX lub CHECKLISTBOX.
W przypadku COMBOBOX słownik jest jedynie sugestią i można wpisywać inne wartości niż pochodzące ze słownika. W przypadku EDIT i DROPDOWN wybrana wartość musi pochodzić ze słownika, a w przypadku CHECKCOMBOBOX i CHECKLISTBOX możemy wybrać wiele wartości na podstawie listy pochodzącej ze słownika.
Aby kontrolki COMBOBOX i DROPDOWN działały poprawnie, relacja zdefiniowana na polu musi dotyczyć obiektu biznesowego z tej samej bazy danych, a obiekt musi być oparty o tabelę lub o zapytanie SQL ale ze wskazaną tabelą natywną.
Słownikowanie programowe z wykorzystaniem funkcji ShowDict¶
Jeśli masz okno edycji zawierające pola, z poziomu którego powinno się dać wejść do słownika, to możesz wywołać słownik programowo bez zdefiniowania relacji na polu modelu danych. W tym celu:
-
zdefiniuj akcję, która będzie powodowała wejście do słownika. Przykładowo jeśli obiekt biznesowy
NAGFAKposiada poleNAGFAK.KLIENTsłownikowane obiektem biznesowymKLIENCI, gdzie polem łącznikowym jestKLIENCI.REFa polem do wyświetlenia po wyborze ze słownika jestKLIENCI.FSKROT, a okno słownika ma symbolDICT, to przykładowe programowe wywołanie okna słownika może wyglądać następująco:Możliwa jest też filtracja słownika, poprzez dodanie opcjonalnego argumentu.ShowDict("KLIENT", "FSKROT", "COMMON.KLIENCI", "REF", "DICT");Opis parametrów znajdziesz w podpowiedzi edytora C#. FunkcjaShowDict("KLIENT", "FSKROT", "COMMON.KLIENCI", "REF", "DICT", "FSKROT LIKE %a%");ShowDict(...)pokazuje okno słownika w trybie, w którym sam Neos dokleja i obsługuje akcje "Wybierz" i "Anuluj", umożliwia wybranie rekordu i przypisanie wybranego pola wybranego rekordu ze słownika (KLIENCI.REF) do odpowiedniego pola obiektu słownikowanego (NAGFAK.KLIENT). -
w drzewiastej strkturze okna podepnij tą akcję jako dziecko pola, które chcesz słownikować. Akcja powinna mieć szerokość 1 oraz pustą etykietę i ikonę. Może mieć także zdefiniowany skrót klawiszowy (np. F3).
Metoda ShowDict(...) pokaże okno słownika, a w momencie wybrania rekordu ze słownika sama zadba o to aby przypisać wybrany rekord do pola podlegającego słownikowaniu. Metoda ta przełącza rekord w tryb edycji w razie potrzeby natomiast nie zatwierdza zmian w zmodyfikowanym rekordzie. Dlatego najelpiej używać tej metody tylko przy słownikowaniu na oknie edycyjnym, w którym użytkownik ma dostęp do przycisku "Zatwierdź".
Zmiana domyślnego zachowania okna słownika podczas wybierania wartości ze słownika¶
Mamy możliwość wpływania na zachowanie akcji "Wybierz" / "Anuluj" na oknie słownika pokazanym poprzez metodę ShowDict(...) lub poprzez słownikowanie w pełni automatyczne.
Jeżeli chcemy zmienić działanie przycisku "Wybierz" należy w obiekcie słownika odziedziczyć metodę SelectFromDictionary() i napisać w niej własny kod. Tak warto zrobić, jeśli chcemy np zrobić dodatkowe warunki, które umożliwiają lub uniemożliwiają wybranie danego rekordu ze słownika. Np w taki sposób:
public void SelectFromDictionary()
{
if(this.QUANTITY.AsDecimal<=0)
ShowBalloonHint("Ten towar jest w niewystarczającej ilości");
else
base.SelectFromDictionary();
}
Można także ukryć standardowe przyciski "Wybierz" / "Anuluj" zaznaczając checkbox "Ukryj przyciski wybierz/anuluj" we właściwościach formy, którą wyświetlamy jako słownik. Jeżeli checkbox będzie niewidoczny, należy zmienić symbol formy na "DICT". W takim wypadku możesz napisać własną akcję, której zadaniem jest wybranie wartości ze słownika i umieścić ją jako przycisk na formie w odpowiednim miejscu (najlepiej w prawym dolnym rogu formy). Przykładowy kod takiej akcji może wyglądać następująco:
public void SelectThisRecord()
{
Result = this.REF;
CloseForm();
}
Powyższy kod spowoduje, że pole this.REF stanie się wartością zwracaną przez słownik, a samo okno słownika zostanie zamknięte. Jeśli okno słownika było wywołane przez ShowDict(...) lub poprzez słownikowanie w pełni automatyczne, to Neos sam zadba o to aby wartość przekazana jako Result została przypisana do pola, z którego wywołano okno słownika.
Słownikowanie w pełni programowe z własną implementacją wybrania wartości ze słownika¶
Zdarza się, że proces wyboru wartości ze słownika jest w pełni zindywidualizowany, bo np w wyniku naciśnięcia przycisku "Wybierz" należy przypisać wartości do kilku pól. W takim wypadku możemy okno słownika pokazać poprzez wywołanie metody ShowForm(...) zamiast ShowDict(...). Dzięki temu ominiemy standardowy mechanizm neosa, który dba o przypisanie odpowiedniego pola z wybranego rekordu słownika, do pola, z którego wywołaliśmy słownikowanie. Przykład wywołania takiego okna wygląda następująco:
public void ShowFindDocumentDict()
{
Contexts c = new Contexts();
c.Add("_complaintpos", this.REF);
DateTime dateParam = DateTime.Now.AddYears(-1);
if (!string.IsNullOrEmpty(this.CSOCOMPLAINT_DATECREATE))
{
dateParam = this.CSOCOMPLAINT_DATECREATE.AsDateTime.AddYears(-1);
}
c.Add("_data_param", dateParam);
c.Add("_klient", this.CSOCOMPLAINT_KLIENT);
c.Add("_odbiorca_param", this.CSOCOMPLAINT_ODBIORCA);
c.Add("_quantity_param", this.QUANTITY);
c.Add("_wersjaref", this.VERS_REF);
ShowForm("CSO_COMPLAINTPOS_FIND_DOCUMENTS", "DICT", c);
}
public void SetComplaintPosDoc()
{
COMPLAINTPOS complaintpos = ParentObject as COMPLAINTPOS;
if(complaintpos != null)
{
complaintpos.DOCTYPE = this.DOCTYPE;
complaintpos.DOCID = this.DOCID;
complaintpos.DOCPOS = this.DOCPOS;
}
this.CloseForm();
}
Jeśli chcemy, aby akcja wybrania wartości ze słownika zadziałała także bez wchodzenia do okna edycji rekordu, to kod odpowiedzialny za wybór wartości ze słownika i przypisanie jej do właściwego pola powinno zostać otoczone wywołaniem funkcji EditRecord() i PostRecord(), np tak:
public void SetComplaintPosDoc()
{
COMPLAINTPOS complaintpos = ParentObject as COMPLAINTPOS;
if(complaintpos != null)
{
complaintpos.EditRecord();
complaintpos.DOCTYPE = this.DOCTYPE;
complaintpos.DOCID = this.DOCID;
complaintpos.DOCPOS = this.DOCPOS;
complaintpos.PostRecord();
}
this.CloseForm();
}
Słownikowanie z wykorzystaniem okien słowników wbudowanych w VCL (np. DictTowary)¶
Okno napisane w technologii Neos jest w stanie wywołać wbudowane VCL-owe okno słownika (np. DictTowary), ale działa to poprawnie dopiero od wersji 6.0.15 i 5.4.22 (temat TSU-2138). Realizujemy je dokładnie tak samo, jak opisano w podrozdziale "Słownikowanie programowe z wykorzystaniem funkcji ShowDict". Do poprawnego działania słownikowania wystarczy napisać taką akcję jak niżej i w definicji okna podpiąć ją jako dziecko pola z KTM-em.
public void SelectFromTOWARY()
{
EditRecord();
CallFunction("SimpleDictionary","FieldName=KTM;DictTable=TOWARY;DictField=KTM");
}
Funkcje do wyświetlania komunikatów - ShowMessageBox, ShowBalloonHint¶
Istnieje możliwość wyświetlania informacji użytkownikowi za pomocą komunikatów. Można to zrealizować na dwa sposoby:
- za pomocą okna modalnego z komunikatem (funkcja ShowMessageBox)
- za pomocą dyskretnej podpowiedzi w pasku systemowym(funkcja ShowBalloonHint)
Funkcja ShowMessageBox pozwala wyświetlić komunikat w oknie z przyciskami, których może być maksymalnie 4. Do każdego przycisku można przypisać akcję Neosa. Wykonywana jest w sposób asynchroniczny (nie zwraca parametru informującego, który z przycisków został naciśnięty). Obsługa przycisków odbywa się po przez zdefioniowanie akcji i wywołanie metod wykonawczych, w których zawarta jest logika obsługi przycisku. Jeśli akcja podpięta do przycisku nie posiada metody wykonawczej to taki przycisk spowoduje zamknięcie okna komunikatu. Alternatywnie można wywołać metody statyczne bez wcześniejszego zdefiniowania akcji za pomocą GUI.CreateStaticActionInfo(), gdy funkcja jest parametryczna należy dodać je StaticActionInfo.AddParameter() należy jednak pamiętać, że w ten sposób przekazane parametry mogą być tylko typu string.
Funkcja ShowBalloonHint pozwala wyświetlić komunikat w pasku systemowym, który nie blokuje interfejsu użytkownikowi. Do funkcji można przypisać jedną akcję Neos, która zostanie wykonana w momencie kliknięcia w komunikat.
Akcje funkcji komunikatów¶
Do akcji zdefiniowanych w obiekcie można odwołać się z poziomu kodu poprzez właściwość Actions aktualnego obiektu. Przykładowo jeśli mamy w obiekcie zdefiniowaną akcję o symbolu 'WyswietloOkno' to w edytorze możemy użyć następującego kodu:
this.Actions.WyswietlOkno
Dynamiczne tworzenie akcji¶
Istnieje rónież możliwość tworzenia akcji bezpośrednio w edytorze kodu Neos Experta w sposób dynamiczny. Tak zdefinowana akcja będzie miała charakter chwilowy tzn. będzie widoczna tylko i wyłącznie w miejscu jej utworzenia. Akcję dynamiczną możemy utworzyć za pomocą następującej instrukcji:
this.Actions.CreateAction(label, icon ,method)
Akcja dynamiczna musi mieć zdefiniowaną etykietę oraz opcjonalnie może mieć ustawione takie cechy jak: ikona oraz metoda wykonawcza.
Parametryzacja metod wykonawczych akcji¶
Akcje pozwalają również na przekazywanie do ich metod wykonawczych parametru z pewną wartością. Aby przekazać do metody wykonawczej akcji parametr należy w edytorze użyć następującjej konstrukcji:
this.Actions.WyswietlOkno.SetParam("13");
SetParam przyjmuje jako argument typ object, więc możemy przekazać zmienną dowolnego typu który jest konwertowalny do objectu. Metoda wykonawcza powinna mieć definiowany argument, typu object z wartością domyślną np.
void MetodaWykonawcza(object param = NULL)
{
}
W tak zdefinowanej metodzie możemy odwołać się do wartości parametru przekazanej za pomocą SetParam, czyli w naszym przypadku param będzie miał wartość równą "13".
Przykład użycia¶
Załóżmy, że mamy w programie listę zamówień klienta i potrzebujemy oprogramować funkcjonalność generowania faktur. Chcielibyśmy, aby użytkownik klikając w menu mógł wystawić klientowi fakturę. Przed wystawieniem faktury program powienien sprawdzić czy klient przypadkiem nie ma przeterminowanych płatności. Po wygenerowaniu powinna być możliwość podglądu faktury.
Możemy taką funkcjonalność zrealizować w następujący sposób:
- Tworzymy akcję o symbolu 'SprawdzPlatnosci', która będzie widoczna w menu kontekstowym
- Tworzymy akcję o symbolu 'GenerujFakture', w której będzie kod generujący nową fakturę.
W metodzie wykonawczej akcji uruchamiającej sprawdzanie płatności (o symbolu 'SprawdzPlatnosci'), wyświetlamy komunikat z prośbą o potwierdzenie wykonania czynności:
void MenuSprawdzPlatnosci()
{
string idZam = this.ID;
if( SprawdzPlatnosci(idZam) == true)
MetodaWykonajFakture(idZam);
else
{
// wywołujemy funkcję ShowMessageBox: i ustwiamy w nim dwie akcje
// pierwsza jest zdefiniowana w obiekcie posiada metodę wykonawczą w parametrze przekazujemy id zamówienia do tej metody
// druga to akcja dynamiczna, w której zdefiniowano etykietę, ikonę, ale nie zdefiniowano metody wykonawczej
// dzięki temu komunikat będzie wyświetlony z dwoma przyciskami drugi przycisk będzie miał czerwoną ikonę z krzyżykiem,
// a ponieważ nie ma metody wykonawczej, to kliknięcie przycisk spowoduje tylko zamknięcie okna komunikatu
ShowMessageBox("Klient posiada przeterminowane płatności, wystawić fakturę?", "Generowanie faktury",
IconType.QUESTION, this.Actions.GenerujFakture.Param(idZam), this.Actions.CreateAction("Nie", "MI_REDX"));
}
}
Metoda wykonawcza akcji o symbolu 'GenerujFakture' wygląda następująco:
// W metodzie wykonawczej deklarujemy argument typu string z wartością domyślną
// Uwaga: Metoda ''MetodaWykonajFakture'' wykonywana jest w dwóch przypadkach:
// * wywołanie w kodzie metody ''MenuSprawdzPlatnosci''
// * jako metoda wykonawcza akcji o symbolu 'GenerujFakture'.
void MetodaWykonajFakture(string param = "")
{
if(param != string.Empty)
{
string symbolFaktury = GeneracjaFaktury(param); // to jest jakaś metoda, która generuje na podstawie id zamówienia
// Po utworzeniu faktury, tworzymy dyskretny komunikat z informacją
// Do akcji podpinamy metodę wykonawczą 'Wyswietl'
// przekazujemy również w parametrze symbol wygenerowanej faktury
ShowBalloonHint("Kliknij aby wyświetlić.", "Utworzono fakturę o symbolu " + symbolFaktury,
IconType.INFORMATION, this.Actions.CreateAction("Faktura", "", this.Wyswietl ).SetParam(symbolFaktury ));
}
void Wyswietl(string param = "")
{
if(param != string.Empty)
PokazFakture(param); // jakaś metoda, która wyświetla fakturę na postawie podanego symbolu
}