Есть dbf таблица "каналы" (без индексов, локально): | Код | CREATE TABLE CHANNELS ( ; CHANNEL N(2) NOT NULL, ; PACKAGE C(50) NOT NULL, ; APP_NAME C(50), ; RUN_FILE C(254), ; BOARD_ID N(2), ; LINE_TYPE C(10), ; LINE_NUM N(2), ; LOCKED N(1) )
|
В программе (C++ Builder, "лишний" код не привожу) - модуль данных: | Код | class Tdata_mod : public TDataModule { __published: TAdsSettings *ads_settings; TAdsConnection *ads_connection; TAdsTable *channels; void __fastcall channelsAfterInsert( TDataSet *DataSet ); }
void __fastcall Tdata_mod::channelsAfterInsert( TDataSet *DataSet ) { int new_num = DataSet->RecordCount + 1; AnsiString package = main_form->channels->package_cbox->Text;
DataSet->SetFields( ARRAYOFCONST(( new_num // CHANNEL N(2) , package // PACKAGE C(50) , Null // APP_NAME C(50) , Null // RUN_FILE C(254) , 0 // BOARD_ID N(2) , Null // LINE_TYPE C(10) , 0 // LINE_NUM N(2) , 0 )) ); // LOCKED N(1) }
|
Базовый (абстрактный) класс просмотра и редактирования (слева - грида и кнопки "добавить, редактировать, удалить", справа - панель, где будут контролы доступа к полям): | Код | class Tbase_frame : public TFrame { __published: TPanel *panel_left; TDBGrid *left_grid; TPanel *left_btn_bar; TBitBtn *btn_add; TBitBtn *btn_edit; TBitBtn *btn_del;
TSplitter *panel_splitter;
TPanel *panel_right; TPanel *right_data; TPanel *right_btn_bar; TBitBtn *btn_save; TBitBtn *btn_cancel;
TDataSource *data_source;
void __fastcall btn_addClick( TObject *Sender ); void __fastcall btn_editClick( TObject *Sender ); void __fastcall btn_delClick( TObject *Sender );
void __fastcall btn_saveClick( TObject *Sender ); void __fastcall btn_cancelClick( TObject *Sender );
public: __fastcall Tbase_frame( TComponent* Owner ); virtual void __fastcall show(); virtual void __fastcall hide(); protected: virtual void __fastcall to_modify( TObject *Sender ); virtual void __fastcall to_view( TObject *Sender ); }; //--------------------------------------------------------------------------- __fastcall Tbase_frame::Tbase_frame( TComponent* Owner ) : TFrame( Owner ) { to_view( this ); } //--------------------------------------------------------------------------- void __fastcall Tbase_frame::btn_addClick( TObject *Sender ) { data_source->DataSet->Insert(); to_modify( Sender ); } //--------------------------------------------------------------------------- void __fastcall Tbase_frame::btn_editClick( TObject *Sender ) { data_source->DataSet->Edit(); to_modify( Sender ); } //--------------------------------------------------------------------------- void __fastcall Tbase_frame::btn_delClick( TObject *Sender ) { data_source->DataSet->Delete(); } //--------------------------------------------------------------------------- void __fastcall Tbase_frame::btn_saveClick( TObject *Sender ) { data_source->DataSet->Post(); to_view( Sender ); } //--------------------------------------------------------------------------- void __fastcall Tbase_frame::btn_cancelClick( TObject *Sender ) { data_source->DataSet->Cancel(); to_view( Sender ); } //--------------------------------------------------------------------------- /*virtual*/ void __fastcall Tbase_frame::show() { data_source->DataSet->Open(); } //--------------------------------------------------------------------------- /*virtual*/ void __fastcall Tbase_frame::hide() { data_source->DataSet->Close(); } //--------------------------------------------------------------------------- /*virtual*/ void __fastcall Tbase_frame::to_modify( TObject *Sender ) { left_btn_bar->Visible = false; right_btn_bar->Visible = true; left_grid->Enabled = false; } //--------------------------------------------------------------------------- /*virtual*/ void __fastcall Tbase_frame::to_view( TObject *Sender ) { left_grid->Enabled = true; right_btn_bar->Visible = false; left_btn_bar->Visible = true; }
|
Фрейм, работающий с таблицей "каналы": | Код | class Tchannels_frame : public Tbase_frame { __published: TPanel *left_package; TLabel *package_label; TComboBox *package_cbox;
TLabel *run_file_label; TDBEdit *run_file_edit;
TDataSource *packages_ds;
void __fastcall package_cboxChange(TObject *Sender);
public: __fastcall Tchannels_frame(TComponent* Owner); virtual void __fastcall show();
private: virtual void __fastcall to_modify( TObject *Sender ); virtual void __fastcall to_view( TObject *Sender ); void __fastcall fill_combobox_list( TComboBox *combo_box, TDataSource *data_src, AnsiString field_name ); }; //--------------------------------------------------------------------------- /*virtual*/ void __fastcall Tchannels_frame::show() { Tbase_frame::show(); packages_ds->DataSet->Open(); fill_combobox_list( package_cbox, packages_ds, "PACKAGE" ); // наполняем комбо данными packages_ds->DataSet->Close(); package_cboxChange( this ); } //--------------------------------------------------------------------------- void __fastcall Tchannels_frame::package_cboxChange(TObject *Sender) { data_source->DataSet->Filtered = false; data_source->DataSet->Filter = "PACKAGE = '" + package_cbox->Text + "'"; data_source->DataSet->Filtered = true; data_source->DataSet->Refresh(); } //--------------------------------------------------------------------------- /*virtual*/ void __fastcall Tchannels_frame::to_modify( TObject *Sender ) { Tbase_frame::to_modify( Sender );
package_cbox->Enabled = false; run_file_edit->Color = modify_bkg_color; run_file_edit->ReadOnly = false; } //--------------------------------------------------------------------------- /*virtual*/ void __fastcall Tchannels_frame::to_view( TObject *Sender ) { run_file_edit->Color = view_bkg_color; run_file_edit->ReadOnly = true; package_cbox->Enabled = true;
Tbase_frame::to_view( Sender ); }
|
Идея такова - в гриде слева отображаем записи (2 поля - "channel" и "app_name") для навигации по таблице (всегда ReadOnly). На панели справа - контролы по остальным полям, доступные для просмотра/редактирования (в приведенном коде - только TDBEdit *run_file_edit - поле RUN_FILE). По нажатию кнопок "Добавить" или "редактировать" контролы в правой панели становятся активны и доступны для редактирования, а грид дизейблится до окончания редактирования. Без фильтра все работает хорошо - есть другие фреймы по другим таблицам. В TComboBox *package_cbox выбирается значение фильтра и в package_cboxChange присваивается - тоже все работает, в гриде видна отфильнорованная по полю PACKAGE инфа из таблицы. НО! Когда добавляется новая (Insert + SetFields в обработчике OnAfterInsert) или начинает редактироваться (Edit) текущая запись, то при потере фокуса гридой - например, переход к TDBEdit *run_file_edit для ввода данных - текущая запись сохраняется (добавленная - пустой) и активной (в гриде) становится первая запись, с учетом установленного фильтра. Вопрос - как редактировать существующие и вновь добавленные записи при ативном фильтре? Что я делаю не так?
|