So this drag and drop problem only appears to happen when it is bound to a data source, rather than filled with treeviewitems.
Here's the xaml and code-behind to reproduce:
To reproduce, simply check one of the children, and reorder the children. If a checked child is reordered, it loses its checked status (which seems reasonable); but if another child is reordered, or there are any checked children, the parent's checked state goes to indeterminate.