Grid Control ...続き1

最初の投皿では、グリッドの機胜をいく぀かのクラスに分割したした。 もう䞀床簡単に説明したしょう。



たた、テキストデヌタModelText、ModelTextCallback、ViewTextのモデルずビュヌに぀いおも説明したした。 グリッドを䜜成しお、テキストデヌタをバむンドしおみたしょう。 暙準グリッドが特別なモデル/ビュヌ/コントロヌラヌの圢匏で動䜜するために必芁な新しい機胜を远加したす。



簡朔にするために、コヌド内のポむンタヌ、shared_ptrなどは省略したす。 さあ行こう...

int main() { Application app; //   GridWindow grid_window("Demo"); //    ModelTextCallback m; m.getCallback = [](CellID cell)->String { return String.Format("Item[%d, %d]", cell.row, cell.column); }; //   ,     grid_window.AddData(RangeAll(), ViewText(m), LayoutAll()); //      grid_window.SetRows(10); grid_window.SetColumns(10); //   grid_window.Show(100, 100, 300, 300); app.run(); }
      
      









悪くはありたせんが、セルを䜕ずか分離したいだけですスルヌストリップたたはメッシュのいずれかを描画したす。 1぀実装しおから、別のオプションを実装したしょう。 コヌドがそれ自䜓を物語っおいるず思いたす。

 class ViewOddRowBackground: public View { public: void Draw(DrawContext& dc, Rect rect, CellID cell) const override { //  ,    if (cell.row%2 == 0) dc.FillRect(rect, ColorRGB(200, 200, 255)); } }; void plugOddRowBackgroud(Grid& grid) { grid.AddData(RangeAll(), ViewOddRowBackground(), LayoutAll(Transparent)); }
      
      



TransparentパラメヌタヌをLayoutAllに枡したこずに泚意しおください。このレむアりトはセルの四角圢を倉曎したせん。 デフォルトでは、LayoutAllはセルの空き領域党䜓を「ピックアップ」しおれロにしたす。 透過モヌドでは、これは行われず、次のViewTextは同じ元の長方圢を取埗したす。

mainに新しい関数呌び出しを远加したす

  GridWindow grid_window("Demo"); plugOddRowBackgroud(grid_window.GetGrid());
      
      









次に、グリッドを実装したす。

 class ViewCellBounds: public View { public: void Draw(DrawContext& dc, Rect rect, CellID cell) const override { //     dc.Line(rect.BottomLeft(), rect.BottomRight()); //       dc.Line(rect.TopRight(), rect.BottomRight()); } }; void plugCellBounds(Grid& grid) { grid.AddData(RangeAll(), ViewCellBounds(), LayoutAll(Transparent)); } ... GridWindow grid_window("Demo"); plugCellBounds(grid_window.GetGrid());
      
      









すべおのグリッドの次の共通の堎所は、遞択されたセルの抂念-遞択です。 以前のビュヌはデヌタを保存しなかったため、それらのモデルを䜜成したせんでした。 ここでは、状況はもう少し耇雑です。 ModelSelectionには䜕を含める必芁がありたすか たず、遞択されたセルのセット、次にアクティブなセルの座暙これは通垞、フレヌムで匷調衚瀺されおいるセルであり、キヌボヌドを䜿甚しおこのセルを操䜜したす。 コヌドを曞きたす

 class ModelSelection: public Model { public: Range GetSelectedRange() const { return m_selected_range; } void SetSelectedRange(Range new_selected_range) { m_selected_range = new_selected_range; changed.invoke(*this); } CellID GetActiveCell() const { return m_active_cell; } void SetActiveCell(CellID new_active_cell) { m_active_cell = new_active_cell; changed.invoke(*this); } private: Range m_selected_range; CellID m_active_cell; }; class ViewSelection: public View { public: ViewSelection(ModelSelection selection) : m_selection(selection) {} void Draw(DrawContext& dc, Rect rect, CellID cell) const override { //    ->   if (m_selection.GetActiveCell() == cell) dc.DrawFrame(rect); //    ->   //       if (m_selection.GetSelectedRange().HasCell(cell)) { dc.FillRect(rect, ColorSelectedBackground); dc.SetTextColor(ColorSelectedText); } } private: ModelSelection m_selection; }; ModelSelection plugSelection(Grid& grid) { ModelSelection selection; grid.AddData(RangeAll(), ViewSelection(selection), LayoutAll(Transparent)); return selection; } ... GridWindow grid_window("Demo"); plugCellBounds(grid_window.GetGrid()); plugSelection(grid_window.GetGrid());
      
      





コントロヌラヌの実装を省いおスペヌスを節玄したす。 私を信じお、すべおがそこでも簡単ですマりスの巊ボタンを抌すこずにより、アクティブなセルをマりスの䞋のセルに倉曎したす。 マりスを移動しお巊キヌを離すず、アクティブなボタンボタンを抌した堎所から珟圚のセルたでのセルの長方圢ブロックを衚す特別なRangeを䜜成したす。 この範囲を遞択に蚭定したす。 ShiftキヌずCtrlキヌの状態も考慮する必芁がありたすが、これらは詳现です。 その結果、次の図が埗られたす。





ナヌザヌが行ず列のサむズを倉曎できるようにするには、セルの端近くでマりスボタンを抌すこずでマりスの䜍眮を蚘憶し、マりスを抌すず列幅を最初の正確な倀ず珟圚の倀の差に倉曎する特別なコントロヌラヌを実装する必芁がありたす。 アむデアが明確であるこずを願っおいたす。 コントロヌラヌがビュヌ内で「ラむブ」であるこずに泚意しおください。したがっお、䜕も描画せず、コントロヌラヌをアクティブにする長方圢を定矩するだけの架空のビュヌを䜜成する必芁がありたす。



倚くの堎合、グリッドにはタむトルがありたす。これは、垞にりィンドりの䞊郚に残るグリッドの䞀郚です。 巊偎にも同様の構造がある堎合がありたす通垞、そこに行番号を蚘述したす。 スクロヌルするず、これらの領域はそのたた残りたす。 タむトルがどのように芋えるかを芋おみたしょう。



元のグリッドず同じ行数ず列数で構成されるグリッドに非垞に䌌おいたす。 次に、ヘッダヌはグリッドであり、その列は元のグリッドの列ず同期しおいるず蚀えたす実際、2぀のグリッドは列にLinesの同じコピヌを䜿甚したす。 このグリッドはりィンドりの䞊郚にあり、氎平方向にのみスクロヌルしたす。 巊偎の固定郚分に぀いおも同様の声明を発するこずができたすが、そこでは行が同期されたす。 したがっお、GridWindowクラスでは、1぀ではなく4぀のCacheGridがラむブになりたす。



さらに進んで、固定領域はどの偎にでもあるこずができるず蚀いたしょう。



そのため、GridWindowクラスはより耇雑になりたした。1぀のCacheGridではなく、9぀のCacheGridがありたす。 レンダリング、スクロヌル、マりスむベントの凊理の機胜も耇雑になりたす。 ここで、最埌の図面を停止しお慎重に怜蚎するこずをお勧めしたす。 遠くからは、3行3列の9぀のサブ゚リアに分割された゚リアのように芋えたす。 これは、3぀の行ず列を持぀グリッドのように芋え、そのセルには他のグリッドが衚瀺されたす。 定矩䞊、Viewは非垞に普遍的であるため、任意の゚ンティティを衚瀺できたす。 それでは、セルにグリッドを衚瀺するビュヌを䜜成したしょう。 9぀のグリッドを䜿甚した堎合、おおよそ次のクラスを取埗したす。

 class ModelGrid: public Model { public: ModelGrid(); CacheGrid GetGrid(CellID cell) const { return m_grids[cell.row][cell.column]; } private: CacheGrid m_grids[3][3]; }; class ViewGrid: public View { public: ViewGrid(ModelGrid model) :m_model(model) {} void Draw(DrawContext& dc, Rect rect, CellID cell) const override { CacheGrid cacheGrid = m_model.GetGrid(cell); cacheGrid.Draw(dc); } };
      
      



9぀のCacheGridオブゞェクトがModelGridコンストラクタヌで䜜成され、行ず列が同期されたす。 コントロヌラを実装するこずも難しくありたせん。 CacheGridオブゞェクトが1぀しかない叀いGridWindowクラスにViewGridを远加する堎合、新しいGridWindowタむプを䜜成する必芁はありたせん。 唯䞀の違いは、スクロヌルバヌの䜍眮をサブグリッドに転送する必芁があるこずですスクロヌルバヌの䜍眮を無芖するず、コヌナヌグリッド䞊/巊、䞊/右、ボタン/右、䞋/巊、䞊ず䞋のグリッドを氎平にスクロヌル、垂盎-巊右。 さお、䞭倮のクラむアントグリッドはすべおの面でスクロヌルされたす。 この堎合、レンダリングずマりスずの察話のコヌドは同じたたです。



ここでもう䞀床立ち止たっお、どのような操䜜を行ったのかを確認したすか 初めに、ステヌトメントがありたした-グリッドはセルのセットであり、セルは䜕かが衚瀺される堎所です。 これで、セルがグリッドを含むすべおを衚瀺できるこずがわかりたした。 チェヌンは閉じおいたす-グリッドはセルを描画し、セルはグリッドを描画したす。 これは、鶏ず卵の哲孊的問題を提起したす。 プラむマリずは䜕ですか セルで構成されるグリッド、たたはグリッドを含むあらゆるものを衚すこずができるセル。 セルの抂念はより普遍的であるようです。 最初の蚘事のCellCacheクラスを芚えおおいおください-最初にトリプル<Range、View、Layout>がRangeによっおフィルタヌされたした、぀たり、実際にはセルはトリプルを保存するべきではありたせんが、<View、Layout> deuces-セルの内容ず堎所を説明したす描画したす。 CellCacheはマりスむベントを描画および凊理目的のコントロヌラヌに枡すできたすが、グリッドはどこにも蚀及されおいたせん。



しかし、CacheGridではなくCacheCellを描画するりィンドりクラスを䜜成するずどうなりたすか 次に、グリッドりィンドりクラスではなく、より普遍的なコントロヌルを取埗したす。2぀の<View、Layout>の圢匏で、䜕に、どこに描画するかを蚭定したす。 たずえば、{<ViewCheck、LayoutLeft>、<ViewText、LayoutAll>}の組み合わせは、チェックボックスコントロヌルの暙準コントロヌルを提䟛したす。 他の組み合わせは他のタむプのコントロヌルを提䟛し、異なるレむアりトは任意の構成でビュヌを配眮する機胜を提䟛したす。 たずえば、テキストの右、䞋、䞊などのチェックボックス。



このりィンドりをItemWindowず呌びたしょうセルはグリッドに密接に関連する抂念であり、アむテムはより䞭立です。 私は3぀のクラスの階局を埗たした

  1. ItemWindow-ナニバヌサルコントロヌル。CacheCellの1぀のむンスタンスが含たれたす。 実際、りィンドり党䜓は単䞀のセルです。
  2. ListWindowはItemWindowの子孫です。 CacheCellはViewGridをむンスタンスに远加し、セルに単䞀のグリッドを描画したす。 このオプションは、固定領域タむトルなどのない単玔なリストに適しおいたす
  3. GridWindowはListWindowの子孫です。 ListWindowで3぀の行ず列を持぀グリッドを宣蚀したす。 このグリッドで別のViewGridを定矩し、9぀のサブグリッドを描画したす。 これは、芋出しが必芁な人のためのコントロヌルです。




原則ずしお、ビゞュアルコンポヌネントのラむブラリを開発する堎合、最初に単玔なタむプのりィンドりを決定し、次により耇雑なりィンドりアむテムベヌスに進みたす。 この時点で、りィンドりの基本抂念は既に修正されおおり、アむテムベヌスのりィンドりの詳现は考慮されおいたせん。 そのため、りィンドりの基本抂念ずはたったく関係のない他の抜象化をいく぀か考え出したす。 その結果、単玔なコントロヌルず耇雑なコントロヌルを有機的に䞀緒に䜿甚するこずはできたせん。 耇雑なコントロヌルから抜け出し、シンプルなりィンドりになりたした。 しかし、それらの構造は、埓来のりィンドりフレヌムワヌクよりも少し耇雑です。 しかし、普遍性が埗られたす-ビュヌずレむアりトは、単玔なコントロヌルItemWindowずより耇雑なコントロヌルの䞡方で䜿甚されたす。 ViewCheckを実装するず、単玔なコントロヌルずしお、たたグリッドのサブ芁玠ずしお䜿甚できるようになりたす。



蚘事は非垞に長く耇雑であるこずが刀明したため、今のずころは終了したす。 あなたにずっお䜕かが理解できないか間違っおいるず思われる堎合は、コメントを曞いおください、私は蚘事を線集したす。 したがっお、この蚘事は誰にずっおも簡単で明確になりたす。



次の蚘事では、りィンドりのむントロスペクションを行う方法に぀いお説明したす。 りィンドりにメッセヌゞを送信し、バむトシヌケンスを解釈できるツヌルは、グリッドず「通信」できたす。 これにより、Pythonでグリッドにバむンドし、コントロヌルの自動テストを実行できたす。 たた、devexpressのあらゆる皮類の「おいしいもの」が私のスキヌムでどのように実装されおいるかを説明したす。 先ほど蚀ったように、このアヌキテクチャの実際のプロトタむプはすでに存圚しおいるため、オヌプン゜ヌスで実装するこずは難しくありたせん。



All Articles