Re: DDX problem: Is DDX even worth the trouble?
Daniel James wrote:
In article news:<eivzQB5xGHA.4972@TK2MSFTNGP03.phx.gbl>, Tom Serface wrote:
I know there is some disagreement as to whether or not to use UpdateData(),
but I find if you use it according to design it works quite well.
I agree ... but I would say that the design does not intend UpdateData to be
called explicitly from user code. It certainly works well if you don't!
Unless you have a whole lot of controls and/or do the updates too often
the cost in time is not to daunting and it's very easy to work within
the framework.
But ... why would you want to call UpdateData any time before the user
dismisses the dialog with "OK". At that point the framework calls UpdateData
for you, so you don't ever need to call it yourself.
[Exception: I do call UpdateData in the implementation of a dialog's "Apply"
button.]
I'm talking about modal dialogs, here, of course. I don't think DDX works
very well in cases where you'd want to use a modeless dialog.
... it was much easier to use it when we had ClassWizard.
Absolutely!
You're right that DDX was not designed (at least well) to do the
validation, ...
DDX (well, DDV) was deigned to do validation. There's an implicit design in
using DDX/DDV that validation is to be deferred until the dialog is
dismissed, and then the value "exchange" (i.e. getting values from controls
and shoving them into C++ variables) and validation occur together. That's
generally speaking the way that Windows apps do this stuff, and although Joe
would say that it's better to do validation on the fly (and cite usability
studies to prove it) I think it's better to provide a "user experience"
that's familiar to the user -- we can't change what the rest of Windows does
but we can be consistent with it.
The DDV mechanism works well if you're prepared to accept deferred
validation, and it's extensible (and there's even class wizard support for
the extensibility ... if you're using VC6).
In the beginning of MFC it was the linkage through DDX/DDV and UpdateData()
that made it so easy to use. I can see how it could be confusing, but it
has worked well for me in lots of programs over the years.
Agreed ... it works well *unless* you want on-the-fly validation. I wouldn't
try to use it for that ... but then I wouldn't recommend doing that.
Cheers,
Daniel.
Daniel:
I would have to say I disagree about not calling UpdataData(), at least
in one particular case. The DDV mechanism assumes implicitly that it is
possible to validate the data items individually. But a complex
data-input screen will often require cross-validation consistency
checks, and furthermore these checks may only be meaningful when the
user indicates he/she is finished by clicking the OK button. In this
situation, the standard base class implementation of OnOK() is useless,
and you need to do something like:
void CMyDialog::OnOK()
{
UpdateData(TRUE);
if(IsValidData())
{
EndDialog(IDOK);
}
}
Now I guess this could be achieved by writing a more complex
DoDataExchange() method for the case where pDX->m_bSaveAndValidate is
TRUE, but for me to do it in OnOK() is more natural.
There is also some use for UpdataData() in OnInitDialog().
BOOL CMyDialog::OnInitDialog()
{
CDialog::OnInitDialog();
PrepareInputs();
UpdateData(FALSE);
return TRUE;
}
This is slightly inelegant, because UpdateData(FALSE) is called twice
(once implicitly, and once explicitly). In fact it is often possible to
NOT call the base class OnInitDialog first (as instructed by the Wizard):
BOOL CMyDialog::OnInitDialog()
{
PrepareInputs();
CDialog::OnInitDialog();
// perhaps other initialization here
return TRUE;
}
Personally, I quite like UpdateData(), and I think I know enough about
how it works to use it correctly. But to each his own.
David Wilkinson