wpf - Animating control size changes dynamically -
i working on kind of menu has "flyout" mode - means remains in compact mode (only ~60px width) until mouse-over. thematic quite tricky since can't animate width of control directly , setting cause fixed size (which not want).
my goal have control can have dynamic size based on it's children , max. available space in it's parent.
my theory: once size changes, measuring called measures maximum available space (far more used). next step arranging. arrangeoverride() called parameter arrangebounds equivalent desired size.
now cache value , if it's different actualsize property, start animation actualsize arrangebounds.width. method return size object return base.arrangeoverride(new size(widthwrapper, arrangebounds.height));
so far have (and it's partially working - widthwrapper dependencyproperty):
protected override size arrangeoverride(size arrangebounds) { if (math.abs(widthwrapper) < 0.01) widthwrapper = arrangebounds.width; if (math.abs(arrangebounds.width - actualwidth) > 0.01) { if (_started & (math.abs(arrangebounds.width - _cache) < 0.01)) return base.arrangeoverride(new size(widthwrapper, arrangebounds.height)); if (math.abs(arrangebounds.width - widthwrapper) < 0.01) return base.arrangeoverride(new size(widthwrapper, arrangebounds.height)); if (_started & !_isexpanding) { console.writeline("re-animate"); // change value if (_cache < arrangebounds.width) _isexpanding = true; _cache = arrangebounds.width; _board.stop(this); _board.children.clear(); _anim = new doubleanimation(widthwrapper, arrangebounds.width, new duration(timespan.fromseconds(0.8))) { easingfunction = new quadraticease() {easingmode = easingmode.easeinout} }; _board.children.add(_anim); storyboard.settarget(_anim, this); storyboard.settargetproperty(_anim, new propertypath(widthwrapperproperty)); _board.begin(this); return base.arrangeoverride(new size(widthwrapper, arrangebounds.height)); } if (!_started) { if (_cache < arrangebounds.width) _isexpanding = true; _cache = arrangebounds.width; _anim = new doubleanimation(widthwrapper, arrangebounds.width, new duration(timespan.fromseconds(1.5))) { easingfunction = new quadraticease() {easingmode = easingmode.easeinout} }; _board.children.add(_anim); storyboard.settarget(_anim, this); storyboard.settargetproperty(_anim, new propertypath(widthwrapperproperty)); _board.begin(this, true); _started = true; } } size animatedsize = new size(widthwrapper, arrangebounds.height); return base.arrangeoverride(animatedsize); }
when starting test project, menu starts in full size , see part of "fading in" right - looks cool. problem is, when switch compact mode there's no animation. instantly becomes ~61px wide. when hover on it, see expanding flickering , randomly jumps previous size.
the problem control misplaced using approach. seems shifts bit away right side when doing animation. mouse-over not detected anymore , tries animate compact size. happens until animation complete , reaches full size (if @ all).
it seems sort of placement-issue it's parent. include gif here, can see mean.
ps: disabled "flyout"-mode, switching normal compact kinda has it's issues (though partially works , quite nice).
any ideas how solve this, make smoothly expand without flickering , other issues? professional ui libraries have example docking windows fade out when unpinned. i'd have kind of effect somehow applied menu. assume possible since i've come close - wpf not support without bit of trickery.
take @ visual state manager , translate transform
essentially you'll want describe open , closed state, , use transforms animate motion between states.
Comments
Post a Comment