c# - Changing Opacity With Reactive Extensions -
<rant>yes, know easier implement in wpf. hear lot. sadly, not possible. </rant>
i writing winforms app, , need "fade" control in & out. transparency impossible in winforms, trying use opacity: idea change alpha channel of each child control's forecolor property on period of time. seems perfect time work on reactive extensions!
my possible solution is:
private void fadeout() { // our list of values alpha channel (255 0) var range = enumerable.range(0,256).reverse().tolist(); // how long between each setting of alpha (huge value example only) var delay = timespan.fromseconds(0.5); // our "trigger" sequence, every half second observable.interval(delay) // paired values range - keep range .zip(range, (lhs, rhs) => rhs) // make onnext changes on ui thread .observeon(synchronizationcontext.current) // every time value rec'd sequence .subscribe( // set alpha value onnext:changealphavalues, // when we're done, hide control oncompleted: () => visible = false, // citizenry onerror: failgracefully); } // no need iterate controls more once - store them here private ienumerable<control> _controls; private void changealphavalues(int alpha) { // controls (via extension method) var controls = _controls ?? this.getallchildcontrols(typeof (control)); // iterate controls , change alpha foreach (var control in controls) control.forecolor = color.fromargb(alpha, control.forecolor); }
... looks impressive, doesn't work. impressive part doesn't work in two ways! gonna "far exceed" on next performance review if keep up. :-)
- (not rx part of problem) alpha values don't seem make difference. despite setting values, display looks same.
- if close window before sequence complete, following error:
system.invalidoperationexception unhandled message: unhandled exception of type 'system.invalidoperationexception' occurred in system.reactive.core.dll additional information: invoke or begininvoke cannot called on control until window handle has been created.
i assume cancellation token come in handy - have no idea how implement it.
i need guidance on:
how close window gracefully (i.e. without throwing error) if sequence still running, , how alpha values colors display after they're changed.
... or maybe wrong approach altogether.
i'm open other suggestions.
i can't winforms transparency part. maybe should split question in two.
but rx part, need cancel subscription when window closed. subscribe
returns idisposable
. should dispose of in closed
event.
and, since assume fade animation might invoked multiple times before window closed, can make use of rx helper serialdisposable
.
finally, interval
returns count. can use simplify observable calculating desired alpha.
private serialdisposable _fadeanimation = new serialdisposable(); private void fadeout() { // how long between each setting of alpha (huge value example only) var delay = timespan.fromseconds(0.5); _fadeanimation.disposable = observable .interval(delay) // 256 animation steps .take(256) // calculate alpha .select(i => 255 - i) .observeon(synchronizationcontext.current) .subscribe( // set alpha value onnext:changealphavalues, // when we're done, hide control oncompleted: () => visible = false, // citizenry onerror: failgracefully); } private void form1_closed() { _fadeanimation.dispose(); }
Comments
Post a Comment