StringGrid - Schreibschutz, Menü



  • hallo
    ich habe zwei probleme mit stringgrids:

    1. ich möchte einzelne Felder schreibgeschützt haben. gibt es dafür auch eine funktion?

    2. wie kann ich es realisieren, dass bei einem klick auf ein einzelnes fenster ein auswahlmenü geöffnet wird, dessen auswahl dann in das feld eingetragen wird?

    danke schon im voraus^^



  • zu 1. s. z.B. das Ereignis OnSelectCell

    Und die 2. Frage verstehe ich nicht: welche Fenster? Oder meinst du "Feld"?
    Ein Kontextmenü (TPopupMenu) kannst du mit PopupMenu zuweisen.
    Dann MenuItems eintragen und entsprechende OnClick-Methoden erzeugen, welche dann den Text in StringGrid->Cells[StringGrid->Col][StringGrid->Row] eintragen.



  • 1. das scheint ja ein ereignis zu sein, was eintritt, wenn die zelle selektiert wird. soll in den code dahinter dann sowas wie MacheZelleLeer() oder wie soll ich das verstehen?

    2. Ja, natürlich meine ich Feld... Weiß auch nicht, warum ich "Fenster" geschrieben habe.
    Kann ich auch für verschiedene Zellen verschiedene Popupmenüs erstellen?



  • Zu ersterem Problem wirst du das Event "SelectCell" benötigen:

    void __fastcall TForm1::StringGrid1SelectCell(TObject *Sender, int ACol,
    	  int ARow, bool &CanSelect)
    {
     if ( ARow == 1 && ACell == 1 || ARow == 1 && ACell == 2 )
         this->StringGrid1->Options >> goEditing;
     else
         this->StringGrid1->Options << goEditing;
    }
    

    Zu zweiterem Problem wie im Vorpost beschrieben. Du kannst natürlich auch zum Beispiel eine ComboBox benutzen, anstatt des PopupMenus.

    Die Platzierung des PopupMenus dann wieder im "SelectCell" Event.



  • oder so

    void __fastcall TForm1::StringGrid1SelectCell(TObject *Sender, int ACol, 
          int ARow, bool &CanSelect) 
    { 
     if ( ARow == 1 )    //wenn Reihe 1 dann kann nicht die Zelle nicht ausgewählt und bearbeitet werden
         CanSelect = false; 
     else 
         CanSelect = true; 
    }
    

    @StefanN
    ACell gibts nicht, nur ACol und ARow



  • Hallo

    Zur 2. Frage kannst du hier eine Lösung finden.

    bis bald
    akari



  • Hallo Linea,

    das war natürlich ein Schreibfehler... 🤡

    An deiner Lösung wäre zu bemängeln, dass es die gesamte Zeile "lahm" legt und der erste Eintrag, sagen wir Zelle (1,1) bei erstmaliger Edition geändert werden könnte.



  • StefanN schrieb:

    An deiner Lösung wäre zu bemängeln, dass es die gesamte Zeile "lahm" legt und der erste Eintrag, sagen wir Zelle (1,1) bei erstmaliger Edition geändert werden könnte.

    Ersteres musst du durch passende Abfrage anpassen.
    Letzteres ist nicht nachvollziehbar.



  • Hallo,

    Letzteres ist nachvollziehbar, falls das StringGrid von Hause aus den Fokus hat. Es ist mir eben nur aufgefallen und wollte darauf aufmerksam machen. Es war ja eine gut gemeinte Kritik.

    Mich würde viel lieber interessieren, ob der Fragende mit unseren Antworten schon etwas anfangen konnte.



  • das erste problem habe ich bewältigt.

    ich bin gerade dabei, das zweite zu versuchen umzusetzen, vllt benötige ich den thread nochmal 😉



  • StefanN schrieb:

    Hallo,

    Letzteres ist nachvollziehbar, falls das StringGrid von Hause aus den Fokus hat. Es ist mir eben nur aufgefallen und wollte darauf aufmerksam machen. Es war ja eine gut gemeinte Kritik.

    Mich würde viel lieber interessieren, ob der Fragende mit unseren Antworten schon etwas anfangen konnte.

    Ne, selbst wenn das StringGrid den Focus hat nicht. Muss bei euch was anderes sein. Aber selbst wenn, muss das Grid den Focus zum Start erhalten ?



  • hallo

    ich habe noch ein problem mit dem menü, weshalb ich den thread nochmal aus den untiefen hervorhole 😛

    ich habe die von akari vorgeschlagene lösung für das menü gewählt.
    jetzt habe ich damit aber die zwei folgenden probleme:
    als erstes würde ich es gern so haben, dass das auswahlfeld wieder verschwindet, ich kann das sicher durch ein einfaches visible=false lösen, aber wo muss das hin?
    ich habe die ComboBox (pComboEditor), muss ich für diese dann ein ereignis einrichten?

    als zweites hat sich in meinen tests ein weiteres problem aufgetan: wenn man auf ein "erlaubtes" feld klickt, öffnet sich die ComboBox. jedoch schreibt die ComboBox auf das feld, was aktiv ist. das soll heißen: klickt der user auf ein erlaubtes feld (und öffnet somit das auswahlmenü), so kann er danach ein unerlaubtes feld anwählen (das menü öffnet sich nicht, sondern bleibt) und der wert, den er im menü wählt wird in das unerlaubte feld geschrieben.

    vllt kann man beide probleme miteinander lösen indem das menü sich wieder schließt, wenn man ein andres feld anklickt, aber: welches ereignis muss ich dafür wie verwenden?

    danke scho im voraus 🙂



  • Zum ersten Problem: Ja, Du brauchst doch mindestens ein OnClick()-Ereignis. Wie machst Du das denn bisher, dass die Auswahl in das StringGrid übertragen wird?
    Schau mal in den FAQ unter 'Komponenten benutzen', insbesondere: zur Laufzeit erstellen, anzeigen und Events zuweisen.

    Das zweite klingt nach einem Denkfehler, respektive Logikfehler im Programm. Zeig doch mal den entsprechenden Code.

    Grüße Joe_M.



  • also hier mal der betreffende quelltext

    void __fastcall TForm3::LoadReasonsToCombo(TComboBox *pComboBox)
    {
      pComboBox->Clear();
      pComboEditor->Items->Add("D1");
      pComboEditor->Items->Add("D2");
      pComboEditor->Items->Add("D3");
      pComboEditor->Items->Add("D4");
      pComboEditor->Items->Add("U");
      pComboEditor->Items->Add("K");
    }
    
    void __fastcall TForm3::PlaceComboEditor(void)
    {
      TRect Rect = StringGrid1->CellRect(StringGrid1->Col,StringGrid1->Row);
      pComboEditor->Top = StringGrid1->Top;
      pComboEditor->Left = StringGrid1->Left;
      pComboEditor->Text = EmptyStr;
      pComboEditor->Top = pComboEditor->Top + Rect.Top +
    	StringGrid1->GridLineWidth;
      pComboEditor->Left = pComboEditor->Left +
    	Rect.Left + StringGrid1->GridLineWidth+1;
      pComboEditor->Height = (Rect.Bottom - Rect.Top) + 1;
      pComboEditor->Width = (Rect.Right - Rect.Left) + 0;
      pComboEditor->Visible = true;
      pComboEditor->SetFocus();
    }
    
    void __fastcall TForm3::ComboEditorChange(TObject *Sender)
    {
      if (StringGrid1->Col == 2 && StringGrid1->Row > 0) {
    		StringGrid1->Cells[StringGrid1->Col][StringGrid1->Row] = pComboEditor->Items->Strings[pComboEditor->ItemIndex];
        }                                                                                                                 
    }    //muss wirklich in das feld wo combobox drin ist!
    
    void __fastcall TForm3::StringGrid1Click(TObject *Sender)
    {
    	TStringGrid* pGrid = dynamic_cast<TStringGrid*>(Sender);
    	if (pGrid->Row > 0 && pGrid->Col == 2) {
    		LoadReasonsToCombo(pComboEditor);
    		PlaceComboEditor();
    		if(pComboEditor->Items->IndexOf(pGrid->Cells[pGrid->Col][pGrid->Row]) >= 0) {
    			pComboEditor->ItemIndex = pComboEditor->Items->IndexOf(pGrid->Cells[pGrid->Col][pGrid->Row]);
    		}
    	}
    }
    

    ich habe schon ein comment nach der funktion, wo das problem liegt (mit den unerlaubtem zugriff)

    es ist also praktisch (fast ) 1 zu 1 nur übernommen.

    danke schomal für die ideen 🙂



  • das ist meine vorläufige lösung eben, die da jetzt zu sehen ist mit dem if()

    😕



  • *push*


Anmelden zum Antworten