Hours and hours later, I finally found the answer. In the JavaScript function that changes the value of the HiddenInfo field, one line is added that (I guess) forces a postback, which then fires the _ValueChanged event in code behind:
<script language="javascript" type="text/javascript">
function CheckCC() {
document.getElementById('HiddenInfo').value="YES";
<%= ClientScript.GetPostBackEventReference(HiddenInfo, "") %>;
}
I dug up the answer here.
Seems like a pretty obscure solution.
The odd thing is that in a previous asp.net design of mine, this wasn't necessary. That's what was really confusing me, and I still don't understand it. But at least I can move forward now.
Thanks everyone for your suggestions.