Font property of System.Windows.Forms.Control

A

Alain Dekker

Some controls (type System.Windows.Forms.Control) do not have a valid font
property. So setting this code:

MyControl.Font = new Font("Arial", cntrl.Font.Size, cntrl.Font.Style);

causing an exception. Indeed, just calling "if (MyControl.font != null)"
causes an exception! Is there a more graceful way to determine if the
Control has a font property so that you can check for the validity of this
operation without throwing an exception?

Thanks,
Alain
 
A

Alain Dekker

The exception "NotSupportedException" and its even visible in the VS
Intellisense. I spend a lot of time reading MSDN documentation, but its not
always easy to find exactly what you want (because for example, there are so
many versions of .NET, Visual Studio, websites discussing this). Its only
when I've exhausted my online searches that I tend to come here.

So, to be clear: I'm recursively setting a new font on all controls on a
form to support Chinese scripts. I've found that the following controls
throw the NotSupported exception:

Panel
PictureBox
ProgressBar

I've re-read several MSDN articles and the inline help and I find nowhere
where MS state that the System.Windows.Form.Panel class does not support the
Font property. In fact, they seem to indicate clearly that it should.

I've now got around the issue by checking the type of the class before
trying to set the font, such as:

bSupported = true;
if (cntrl is Panel)
bSupported = false;

if (bSupported)
TryAndSetFont(cntrl);

Regards,
Alain
 
A

Alain Dekker

Hi Pete,

Thanks for the response.
Not sure what you mean by "visible in the VS Intellisense". Intellisense
is an editor-related feature, not a run-time debugger feature.

Maybe I'm getting mixed up. I mean when you're debugging, you hit the
breakpoint, you run your mouse over a variable, a little window pops up and
shows the variable type, by clicking the little expand box next to the
variable type you can see data about the varaible. Its nearly exactly the
same functionality you get in the "Watch" window. I mean that when I say
"Intellisense", sorry for the confusion. In that window, when I scroll down
to the Font property, that "Watch"-style window shows an exception,
"NotSupportedException".
Yeah, but AFAIK none of the rest of us do any .NET work on CF. I'll bet
this is a straight newbie question on a forum specifically for CF. But
here, all you get is us dummies scratching our heads, because everything
works fine on the desktop.

Fair point. The differences between .NET 2.0 and .NET CF 2.0 are not
massive, though. Usually the MSDN documentation online or the VS inline help
make it quite clear when a feature is supported or not supported in the CF.
Sometimes, as with the Font property of the Panel control, the documentation
is not quite right.
If you find the docs confusing, submit feedback to Microsoft. There's a
ton of documentation on MSDN, most of it for legacy versions, and you can
bet Microsoft isn't sifting through it looking for problems. They will
only know if you tell them.

Thanks, good suggestion. I've gone back online and made the suggestion for
documentation improvements both on the Panel and the Font documentation for
..NET 2.0.
Rather than hard-coding specific types in your code, why not just catch
the
exception:

Thats what I was doing before, but I'm currently going through a sweep
through the code logging whenever an exception occurs (with the aim to try
and remove as many if not all exceptions). After adding this log, I
discovered the repeated crash on the Panel (and other controls). Maybe I'm
old school, but I find this new trend towards writing code that merrily
crashes (which involves putting try/catch blocks everywhere) sloppy. I mean
the previous developer was putting try/catch clocks around *everything*
including really silly things like: label1.Text = "A string"; !! Its a bit
like telling the developer to buy more memory or a faster PC instead of
focussing efforts on performance. By just taking his code and checking how
often it crashed, it was crashing into the except block up to 20-30 times a
minute by jumping around the screens.

Perhaps you have an opinion on that matter. In my opinion, writing code that
doesn't crash is both easier to read, smaller and, I would have thought,
gets better performance.

Thanks again,
Alain
 
A

Arne Vajhøj

Thats what I was doing before, but I'm currently going through a sweep
through the code logging whenever an exception occurs (with the aim to try
and remove as many if not all exceptions). After adding this log, I
discovered the repeated crash on the Panel (and other controls). Maybe I'm
old school, but I find this new trend towards writing code that merrily
crashes (which involves putting try/catch blocks everywhere) sloppy. I mean
the previous developer was putting try/catch clocks around *everything*
including really silly things like: label1.Text = "A string"; !! Its a bit
like telling the developer to buy more memory or a faster PC instead of
focussing efforts on performance. By just taking his code and checking how
often it crashed, it was crashing into the except block up to 20-30 times a
minute by jumping around the screens.

Perhaps you have an opinion on that matter. In my opinion, writing code that
doesn't crash is both easier to read, smaller and, I would have thought,
gets better performance.

You should not decide whether to use exceptions or not on
performance.

It should be based on what it is.

If an error situation is "exceptional" then the
..NET way is to use exceptions.

Throwing and catching an exception do cost a little bit of
CPU, but an app should not have a huge number for exceptional
situations (it would not really be exceptional any more then)
so the overall impact on app performance should be
insignificant.

And you may not necessarily need to put try catch around
every little piece of code. You just need to have it
where you app either can recover or should exit.

Remember one of the main benefits from exceptions is
that they can "jump back" many calls in the call
stack.

Arne
 
A

Arne Vajhøj

Yes, those also existed.

I hope you aren't trying to imply that there was no dojmp.

K&R, C89, C99 and POSIX defines setjmp and longjmp.

Obviously you can have been using a non standard dojmp
wrapper around longjmp or a non-C but C-like language that
used dojmp instead of longjmp.

Arne
 
A

Arne Vajhøj

Yes, they do. I never said they didn't.


Yes, obviously. I never said I wasn't. Oh, and the language wasn't
"C-like". It _was_ C, with non-standard extensions, predating even C89.

Did you read what I wrote above?

K&R also used setjmp and longjmp.

Predating K&R C ????
I'm still trying to figure out what you thought you were adding to the
conversation here.

Preventing anyone from believing there are a C thing called
dojmp.

Arne
 
A

Alain Dekker

Thanks, good reply. I'm aware I need to use try/catch occasionally and (more
importantly) correctly. I'm also aware of the (admittedly small) performance
knock exception handling involves so try to avoid its overuse.

Performance is kinda critical on our system because we're stuck with a
300MHz processor (max), very little memory and astonishly slow (by modern PC
standards) I/O where just getting a DirectyInfo listing of 200 files costs
about 120ms. In case you're wondering, these are low cost machines headed
for food factories.

Thanks again,
Alain
 
A

Alain Dekker

Thanks Peter. You're right, of course. I get a little hung up sometimes. I
am well aware of both the benefits and costs of good exception handling. I'm
trying to continue the correct usage of exception handling while reducing
its overuse.

And thanks also for re-inforcing that the .NET way is to throw exceptions as
a standard error-trapping mechanism. Fair enough, I'll move with the
times...

Alain

Peter Duniho said:
Hi Pete,

Thanks for the response.


Maybe I'm getting mixed up. I mean when you're debugging, you hit the
breakpoint, you run your mouse over a variable, a little window pops up
and
shows the variable type, by clicking the little expand box next to the
variable type you can see data about the varaible. Its nearly exactly the
same functionality you get in the "Watch" window. I mean that when I say
"Intellisense", sorry for the confusion. In that window, when I scroll
down
to the Font property, that "Watch"-style window shows an exception,
"NotSupportedException".

Well, "not supported" is "not supported". It doesn't matter whether your
own code calls the property or the debugger does, the property is still
going to throw the exception.
[...]
Rather than hard-coding specific types in your code, why not just catch
the exception:

Thats what I was doing before, but I'm currently going through a sweep
through the code logging whenever an exception occurs (with the aim to
try
and remove as many if not all exceptions). After adding this log, I
discovered the repeated crash on the Panel (and other controls). Maybe
I'm
old school, but I find this new trend towards writing code that merrily
crashes (which involves putting try/catch blocks everywhere) sloppy.

Get over it.

Even two decades ago (a kind of "old school" at least by some measures),
we
used setjmp and dojmp in C code, right alongside normal error return
values. In .NET, exceptions are _the_ primary way to return errors. You
can't write .NET code without getting involved with exceptions.
I mean
the previous developer was putting try/catch clocks around *everything*
including really silly things like: label1.Text = "A string"; !! Its a
bit
like telling the developer to buy more memory or a faster PC instead of
focussing efforts on performance. By just taking his code and checking
how
often it crashed, it was crashing into the except block up to 20-30 times
a
minute by jumping around the screens.

Just because one is using exceptions, that doesn't mean one must do so
ignorantly. Perhaps the previous developer did overuse try/catch. But
that doesn't mean you should avoid it when it's needed.
Perhaps you have an opinion on that matter. In my opinion, writing code
that
doesn't crash is both easier to read, smaller and, I would have thought,
gets better performance.

In .NET, "code that doesn't crash" requires try/catch. It's obviously
better to avoid calling code that will throw an exception, but you can't
always do that. When you run into such situations, just put the try/catch
in and move on. A programmer has better ways to spend their time than
dwelling on the issue.

Note that in some situations (perhaps your Font issue is one of them), you
don't have to keep calling the method that throws the exception. You can
detect the exception the first time, and use that information to avoid
calling it in the future.

Pete
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top