How do I format a signed integer to a sign-aware hexadecimal representation?

Is there a way to do this formatting procedure while still adhering to a standard Formatter?

Yes, but you need to make a newtype in order to provide a distinct implementation of UpperHex. Here's an implementation that respects the +, # and 0 flags (and possibly more, I haven't tested):

use std::fmt::{self, Formatter, UpperHex};

struct ReallySigned(i32);

impl UpperHex for ReallySigned {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        let prefix = if f.alternate() { "0x" } else { "" };
        let bare_hex = format!("{:X}", self.0.abs());
        f.pad_integral(self.0 >= 0, prefix, &bare_hex)
    }
}

fn main() {
    for &v in &[15, -15] {
        for &v in &[&v as &UpperHex, &ReallySigned(v) as &UpperHex] {
            println!("Value: {:X}", v);
            println!("Value: {:08X}", v);
            println!("Value: {:+08X}", v);
            println!("Value: {:#08X}", v);
            println!("Value: {:+#08X}", v);
            println!();
        }
    }
}