ComboBox w MVP

ZO
  • Rejestracja:prawie 15 lat
  • Ostatnio:ponad 10 lat
0

Witam,
Zakręciłem się przy próbie umieszczenia comboBox'a w szablonie MVP.
Umieszczam comboBox ma formie. Forma wystawia interface na podstawie którego klasa presenter buduje obiekt. Poprzez interface jest wystawiany obiekt(model) z formy który powinien pobrać/oddać dane. Nie może on jednak (chyba) zawierać obiektu comboBox tylko ewentualnie dane które powinien otrzymać. Teraz nie wiem czy zbudować szablonowy obiekt na wzór comboBoxa który zawiera dataSource, DisplayMember, ValueMember i SelectedValue. Podać mu dane w Modelu i poprzez presentera przekazać do właściwego comboBoxa? Chociaż też nie bo interface nie wystawia comboBox'a. Help :-)
Chyba, że mogę wystawić comboBox'a poprzez interface do presentera - wtedy prościzna ;-)

W takim przypadku byłoby tak:

Model

Kopiuj
 
public class RaportowanieModel : EntityBase
    {
        public int miesiac { get; set; }
        public int rok { get; set; }
        public ComboBox rokComboBox = new ComboBox();
        public ComboBox miesiacComboBox = new ComboBox();
        public DataTable raportyWyborDanychDT { get; set; }
        public DataRow raportyWyborDanychCurrentDR { get; set; }
    }

Presenter

Kopiuj
 public void Initialize(IRaportowanie view)
        {
            zapytanieDataGrid.utworzSELECT("RaportyWyborDanychCalosc_v",
                new List<string> { "*" }, new string[] { "month(dataWaluty)=? AND year(dataWaluty)=?", "dataWaluty DESC" });
            zapytanieDataGrid.dodajParametr("@P1", "int");
            zapytanieDataGrid.dodajParametr("@P2", "int");
            view.raportowanieModel = new Model.RaportowanieModel();
        }

        public void load(IRaportowanie view)
        {
            Pomocne.ComboBoxUstaw.rok(view.raportowanieModel.rokComboBox);
            Pomocne.ComboBoxUstaw.miesiac(view.raportowanieModel.miesiacComboBox);
        }

View

Kopiuj
 
 public Raportowanie()
        {
            InitializeComponent();
            presenter.Initialize(this);
            raportowanieModel.rokComboBox = this.rokComboBox;
            raportowanieModel.miesiacComboBox = this.miesiacComboBox;
        }


        private void Raportowanie_Load(object sender, EventArgs e)
        {
            presenter.load(this);
            presenter.daneDoDataGrid(this);
        }


        #region IRaportowanie

        public RaportowanieModel raportowanieModel
        {
            get { return this.raportowanieModelBindingSource.Current as RaportowanieModel; }
            set { this.raportowanieModelBindingSource.DataSource = value; }
        }

Model -> oczekuje obiektów comboBox
Presenter -> przy wywołaniu Initializera powołuje do życia model
View -> konstruktor przekazuje referencję ze swoich comboBox'ow do tych z modelu
View -> Load pobiera poprzez prezentera dane do comboBox

działa ale mi się nie podoba :/

Pozdrawiam,
Zoritt

edytowany 3x, ostatnio: Zoritt
somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:około 13 godzin
  • Lokalizacja:Wrocław
1

Model ani Presenter nie powinny nic wiedzieć o istnieniu czegoś takiego jak ComboBox. To jest szczegół implementacji znajdujący się w Widoku.
Interfejs IRaportowanie powinien zawierać właściwości, które ustawiasz w Prezenterze, zaś Widok powinien je zaimplementować i ustawić wartości w ComboBoxie. W szczególności powinna być to jakaś lista obiektów, która potem zostanie zbindowana z DataSource oraz wybrany obiekt, który zostanie zbindowany z SelectedValue. Natomiast DisplayMember i ValueMember ustawiłbym po prostu w designerze, chyba nie będą się zmieniały, prawda?

ZO
Teraz mam jasność. Wielkie dzięki!
somekind
Proszę bardzo. Ale jeśli pomogłem, to pisz posty/punktuj/akceptuj, a nie tylko komentujesz.
ZO
Zaraz jak poprawię tego comboBox'a to zawieszę w poście kod, może się komuś przyda
ZO
  • Rejestracja:prawie 15 lat
  • Ostatnio:ponad 10 lat
0

OK. Po poprawkach.
O niebo lepiej ale jeszcze wydaje mi się, że mam za bardzo rozstrzeloną obsługę tego comba.

Model

Kopiuj
 
 public class RaportowanieModel : EntityBase
    {
        public string miesiac { get; set; }
        public string rok { get; set; }
        public string[] rokDataSource { get; set; }
        public string[] miesiacDataSource { get; set; }
        public DataTable raportyWyborDanychDT { get; set; }
        public DataRow raportyWyborDanychCurrentDR { get; set; }
    }

Presenter

Kopiuj
 
 public void Initialize(IRaportowanie view)
        {
            zapytanieDataGrid.utworzSELECT("RaportyWyborDanychCalosc_v",
                new List<string> { "*" }, new string[] { "month(dataWaluty)=? AND year(dataWaluty)=?", "dataWaluty DESC" });
            zapytanieDataGrid.dodajParametr("@P1", "int");
            zapytanieDataGrid.dodajParametr("@P2", "int");
            view.raportowanieModel = new Model.RaportowanieModel();
        }

        public void load(IRaportowanie view)
        {
            view.raportowanieModel.rokDataSource=Pomocne.ComboBoxDane.rok();
            view.raportowanieModel.miesiacDataSource=Pomocne.ComboBoxDane.miesiac();
        }

View

Kopiuj
 public partial class Raportowanie : BaseViewForm, IRaportowanie
    {
        private Presenters.RaportowaniePresenter presenter = new Presenters.RaportowaniePresenter();

        public Raportowanie()
        {
            InitializeComponent();
            presenter.Initialize(this);
        }


        private void Raportowanie_Load(object sender, EventArgs e)
        {
            presenter.load(this);
            this.rokComboBox.DataSource = raportowanieModel.rokDataSource;
            this.rokComboBox.SelectedIndex = 5;
            this.miesiacComboBox.DataSource = raportowanieModel.miesiacDataSource;
            this.miesiacComboBox.SelectedIndex = DateTime.Now.Month - 1;
            presenter.daneDoDataGrid(this);
        }


        #region IRaportowanie

        public RaportowanieModel raportowanieModel
        {
            get { return this.raportowanieModelBindingSource.Current as RaportowanieModel; }
            set { this.raportowanieModelBindingSource.DataSource = value; }
        }

        public DataTable raportowanieDT
        {
            get { return this.raportowanieDTBindingSource.DataSource as DataTable; }
            set
            {
                this.raportowanieDTBindingSource.DataSource = value;
                this.raportowanieDTBindingSource.ResetBindings(false);
            }
        }

        #endregion

Pozdrawiam,
Zoritt

somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:około 13 godzin
  • Lokalizacja:Wrocław
1

Nie podoba mi się to, a konkretnie zawartość Raportowanie_Load. Jest za mądra, a Widok powinien być tak głupi, jak to tylko możliwe.

Ogólnie mówiąc, są dwa rozwiązania:

  1. Każda kontrolka powinna być powiązana z właściwością z interfejsu Widoku (albo dwiema, jeśli poza wartością wymaga źródła danych), które są ustawiane i odczytywane w odpowiednich metodach Prezentera.
  2. Dobrze skonfigurowane BindingSource, które prawidłowo wiąże właściwości klasy Modelu z właściwościami kontrolek.

Zatem albo:

  1. Wszystkie DataSource i SelectedIndex tych ComboBoxów ukryj we właściwościach zaimplementowanych z IRaportowanie oraz ustawianych w metodzie RaportowaniePresenter.Initialize.
  2. Popraw BindingSource, tylko nie wiem, czy w przypadku takiego dziwnego Modelu jak Twój jest to możliwe.
ZO
  • Rejestracja:prawie 15 lat
  • Ostatnio:ponad 10 lat
0

Nieco zniechęciłem się do bindowania comboBox'a z właściwościami modelu. Problem jest taki, że w obsłudze zdarzenia SelectedIndexChanged podbindowana właściwość modelu nie jest jeszcze zmieniona (zmienia się dopiero po opuszczeniu comboBox'a) zatem i tak musiałem ręcznie zmienić wartość tej właściwości ponieważ jest ona (ta wartość) pobierana w prezenterze przez daneDoDataGrid. Może jest na to jakaś rada ale nie wymyśliłem i zostałem przy ręcznej podmianie wartości jak poniżej:

Kopiuj
 
private void rokComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (this.rokComboBox.Visible)
            {
                this.raportowanieModel.rok = this.rokComboBox.SelectedItem.ToString();
                presenter.daneDoDataGrid(this);
            }
        }

Druga sprawa to zmartwiłeś mnie tym "dziwnym modelem" powiem szczerze, spotykać udziwnienia to lubię w Alicji w Krainie Czarów a nie kodzie. Rozumiem, że problem w tym DataTable i DataRow?

Całość po poprawkach:
Model:

Kopiuj
 
 public class RaportowanieModel : EntityBase
    {
        public string miesiac { get; set; }
        public string rok { get; set; }
        public DataTable raportyWyborDanychDT { get; set; }
        public DataRow raportyWyborDanychCurrentDR { get; set; }
    }

Presenter:

Kopiuj
 
class RaportowaniePresenter
    {
        public delegate void eventWlaczStatusBar();
        public event eventWlaczStatusBar wlaczStatusStrip;
        public delegate void eventWylaczStatusBar();
        public event eventWylaczStatusBar wylaczStatusStrip;
        public delegate void eventProgressBar(int ileProcent, string nazwa);
        public event eventProgressBar progressBar;
        private Pomocne.Zapytanie zapytanieDataGrid;
        
        public void Initialize(IRaportowanie view)
        {
            zapytanieDataGrid = new Pomocne.Zapytanie(view);
            zapytanieDataGrid.utworzSELECT("RaportyWyborDanychCalosc_v",
                new List<string> { "*" }, new string[] { "month(dataWaluty)=? AND year(dataWaluty)=?", "dataWaluty DESC" });
            zapytanieDataGrid.dodajParametr("@P1", "int");
            zapytanieDataGrid.dodajParametr("@P2", "int");
            
            view.rokCBDataSource = Pomocne.ComboBoxDane.rok();
            view.rokCBSelectedIndex = 5;
            view.miesiacCBDataSource = Pomocne.ComboBoxDane.miesiac();
            view.miesiacCBSelectedIndex = DateTime.Now.Month - 1;
            view.raportowanieModel = new Model.RaportowanieModel();
        }

        public void daneDoDataGrid(IRaportowanie view)
        {
            zapytanieDataGrid.parametr[0].Value = view.raportowanieModel.miesiac;
            zapytanieDataGrid.parametr[1].Value = view.raportowanieModel.rok;
            view.raportowanieDT = zapytanieDataGrid.wykonajSelect2DataTable();
        }

View:

Kopiuj
 
public partial class Raportowanie : BaseViewForm, IRaportowanie
    {
        private Presenters.RaportowaniePresenter presenter = new Presenters.RaportowaniePresenter();

        public Raportowanie()
        {
            InitializeComponent();
            presenter.Initialize(this);
            toolStripStatusLabel1.Text = "Przetwarzanie danych: ";
            presenter.wlaczStatusStrip+=new RaportowaniePresenter.eventWlaczStatusBar(presenter_wlaczStatusStrip);
            presenter.wylaczStatusStrip+=new RaportowaniePresenter.eventWylaczStatusBar(presenter_wylaczStatusStrip);
            presenter.progressBar+=new RaportowaniePresenter.eventProgressBar(presenter_progressBar);
        }


        private void Raportowanie_Load(object sender, EventArgs e)
        {
            presenter.daneDoDataGrid(this);
        }


        #region IRaportowanie
        public string[] rokCBDataSource
        {
            set { this.rokComboBox.DataSource = value; }
        }

        public int rokCBSelectedIndex
        {
            set { this.rokComboBox.SelectedIndex = value; }
        }

        public string[] miesiacCBDataSource
        {
            set { this.miesiacComboBox.DataSource = value; }
        }

        public int miesiacCBSelectedIndex
        {
            set { this.miesiacComboBox.SelectedIndex = value; }
        }

        public RaportowanieModel raportowanieModel
        {
            get { return this.raportowanieModelBindingSource.Current as RaportowanieModel; }
            set { this.raportowanieModelBindingSource.DataSource = value; }
        }

        public DataTable raportowanieDT
        {
            get { return this.raportowanieDTBindingSource.DataSource as DataTable; }
            set
            {
                this.raportowanieDTBindingSource.DataSource = value;
                this.raportowanieDTBindingSource.ResetBindings(false);
            }
        }
        public DataRow raportowanieCurrentDR 
        {
            get
            {
                if (this.raportowanieDTBindingSource.Current == null) return null;
                else return ((DataRowView)this.raportowanieDTBindingSource.Current).Row;
            }
            set { }
        }
        #endregion

Pozdrawiam,
Zoritt

ZO
  • Rejestracja:prawie 15 lat
  • Ostatnio:ponad 10 lat
0

Wrócę do starego tematu ale właśnie mnie olśniło. Poprzedni przykład zawiera błąd polegający na przeniknięciu modelu do widoku czyli:

Kopiuj
 
view.raportowanieModel = new Model.RaportowanieModel();

Z opisu MVP wynika, że view nie ma mieć pojęcia o istnieniu modelu.
Podsumowując view buduje obiekt w oparciu o klasę prezentera. Prezenter pobiera dane z widoku poprzez interface oraz (prezenter) buduje obiekt w oparciu o klasę modelu. I wtedy wszystko gra.
Niby nic skomplikowanego ...

Pozdrawiam,
Zoritt

Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)