c# - Click and drag scrolling using ScrollViewer -
i allow click , drag scrolling using scrollviewer
(i.e. click anywhere in scrollviewer
, drag or down, , scroll accordingly)
i have stackpanel
nested within scrollviewer
, have scrolling working. believe saw reply somewhere, can't seem find anymore.
this has done using code only.
look @ this code matt hamilton:
public class touchscrolling : dependencyobject { public static bool getisenabled(dependencyobject obj) { homecoming (bool)obj.getvalue(isenabledproperty); } public static void setisenabled(dependencyobject obj, bool value) { obj.setvalue(isenabledproperty, value); } public bool isenabled { { homecoming (bool)getvalue(isenabledproperty); } set { setvalue(isenabledproperty, value); } } public static readonly dependencyproperty isenabledproperty = dependencyproperty.registerattached("isenabled", typeof(bool), typeof(touchscrolling), new uipropertymetadata(false, isenabledchanged)); static dictionary<object, mousecapture> _captures = new dictionary<object, mousecapture>(); static void isenabledchanged(dependencyobject d, dependencypropertychangedeventargs e) { var target = d scrollviewer; if (target == null) return; if ((bool)e.newvalue) { target.loaded += target_loaded; } else { target_unloaded(target, new routedeventargs()); } } static void target_unloaded(object sender, routedeventargs e) { system.diagnostics.debug.writeline("target unloaded"); var target = sender scrollviewer; if (target == null) return; _captures.remove(sender); target.loaded -= target_loaded; target.unloaded -= target_unloaded; target.previewmouseleftbuttondown -= target_previewmouseleftbuttondown; target.previewmousemove -= target_previewmousemove; target.previewmouseleftbuttonup -= target_previewmouseleftbuttonup; } static void target_previewmouseleftbuttondown(object sender, mousebuttoneventargs e) { var target = sender scrollviewer; if (target == null) return; _captures[sender] = new mousecapture { verticaloffset = target.verticaloffset, point = e.getposition(target), }; } static void target_loaded(object sender, routedeventargs e) { var target = sender scrollviewer; if (target == null) return; system.diagnostics.debug.writeline("target loaded"); target.unloaded += target_unloaded; target.previewmouseleftbuttondown += target_previewmouseleftbuttondown; target.previewmousemove += target_previewmousemove; target.previewmouseleftbuttonup += target_previewmouseleftbuttonup; } static void target_previewmouseleftbuttonup(object sender, mousebuttoneventargs e) { var target = sender scrollviewer; if (target == null) return; target.releasemousecapture(); } static void target_previewmousemove(object sender, mouseeventargs e) { if (!_captures.containskey(sender)) return; if (e.leftbutton != mousebuttonstate.pressed) { _captures.remove(sender); return; } var target = sender scrollviewer; if (target == null) return; var capture = _captures[sender]; var point = e.getposition(target); var dy = point.y - capture.point.y; if (math.abs(dy) > 5) { target.capturemouse(); } target.scrolltoverticaloffset(capture.verticaloffset - dy); } internal class mousecapture { public double verticaloffset { get; set; } public point point { get; set; } }
}
there quirks here. noticed scrollviewer beingness loaded, unloaded , loaded 1 time again when content shown.
that meant couldn't hook events in isenabledchanged
method , unhook them in target_unloaded
event handler, because beingness unhooked immediately. instead, i've had hook them in handler loaded event, in turn never gets unhooked.
that means there's of "memory leak" in there, it's 1 i'm prepared live with.
c# wpf scrollviewer
No comments:
Post a Comment