xaml - Wpf disable repeatbuttons when scrolled to top/bottom -
i'm making touchscreen interface uses listbox.
have button above , below listbox page up/down.
i'm trying when scrolled way pageup button gets disabled.
, when scrolled way down pagedown button gets disabled too.
here's code in styles.xaml listbox
<style x:key="{x:type listbox}" targettype="{x:type listbox}"> <setter property="template"> <setter.value> <controltemplate x:key="{x:type listbox}" targettype="{x:type listbox}"> <dockpanel> <repeatbutton x:name="lineupbutton" dockpanel.dock="top" horizontalalignment="stretch" height="50" content="/\" command="{x:static scrollbar.pageupcommand}" commandtarget="{binding elementname=scrollviewer}" /> <repeatbutton x:name="linedownbutton" dockpanel.dock="bottom" horizontalalignment="stretch" height="50" content="\/" command="{x:static scrollbar.pagedowncommand}" commandtarget="{binding elementname=scrollviewer}" /> <border borderthickness="1" borderbrush="gray" background="white"> <scrollviewer x:name="scrollviewer"> <itemspresenter/> </scrollviewer> </border> </dockpanel> </controltemplate> </setter.value> </setter> <setter property="scrollviewer.horizontalscrollbarvisibility" value="hidden"/> <setter property="scrollviewer.verticalscrollbarvisibility" value="hidden"/> <setter property="focusvisualstyle" value="{x:null}" /> </style>
and here's instantiate listbox
<listbox selecteditem="{binding selectedcan}" itemssource="{binding path=selectedkioskcashcans}"> <listbox.itemtemplate> <datatemplate> <contentpresenter content="{binding image}" maxwidth="75" /> </datatemplate> </listbox.itemtemplate> <listbox.itemspanel> <itemspaneltemplate> <virtualizingstackpanel orientation="vertical"/> </itemspaneltemplate> </listbox.itemspanel> </listbox>
i searched around yesterday no luck.
i'm hoping able in xaml.
i'm using images buttons took them out readability above,
like...
<repeatbutton x:name="lineupbutton" dockpanel.dock="top" horizontalalignment="stretch" height="50" command="{x:static scrollbar.pageupcommand}" commandtarget="{binding elementname=scrollviewer}"> <repeatbutton.template> <controltemplate targettype="{x:type repeatbutton}"> <grid> <image name="normal" source="/images/up.png"/> <image name="pressed" source="/images/up.png" visibility="hidden"/> </grid> <controltemplate.triggers> <trigger property="ispressed" value="true"> <setter targetname="normal" property="visibility" value="hidden"/> <setter targetname="pressed" property="visibility" value="visible"/> </trigger> </controltemplate.triggers> </controltemplate> </repeatbutton.template> </repeatbutton>
just use canexecute
method of pageupcommand
that. return false
if no pages left , button become disabled automatically.
edit:
i have created simple attached behavior can used fix problem. set following attached property on scrollviewer
:
<scrollviewer x:name="scrollviewer" z:scrollbarcommandscanexecutefixbehavior.isenabled="true"> <itemspresenter/> </scrollviewer>
and here source code of behavior:
public static class scrollbarcommandscanexecutefixbehavior { #region nested types public class commandcanexecutemonitor<t> t : uielement { protected t target { get; private set; } protected commandcanexecutemonitor(t target, routedcommand command) { target = target; var binding = new commandbinding(command); binding.canexecute += oncanexecute; target.commandbindings.add(binding); } protected virtual void oncanexecute(object sender, canexecuteroutedeventargs e) { } } public class pageupcanexecutemonitor : commandcanexecutemonitor<scrollviewer> { public pageupcanexecutemonitor(scrollviewer scrollviewer) : base(scrollviewer, scrollbar.pageupcommand) { } protected override void oncanexecute(object sender, canexecuteroutedeventargs e) { if (e.handled) { return; } if (equals(target.verticaloffset, 0.0)) { e.canexecute = false; e.handled = true; } } } public class pagedowncanexecutemonitor : commandcanexecutemonitor<scrollviewer> { public pagedowncanexecutemonitor(scrollviewer scrollviewer) : base(scrollviewer, scrollbar.pagedowncommand) { } protected override void oncanexecute(object sender, canexecuteroutedeventargs e) { if (e.handled) { return; } if (equals(target.verticaloffset, target.scrollableheight)) { e.canexecute = false; e.handled = true; } } } #endregion #region isenabled attached property public static bool getisenabled(dependencyobject obj) { return (bool) obj.getvalue(isenabledproperty); } public static void setisenabled(dependencyobject obj, bool value) { obj.setvalue(isenabledproperty, value); } public static readonly dependencyproperty isenabledproperty = dependencyproperty.registerattached("isenabled", typeof (bool), typeof (scrollbarcommandscanexecutefixbehavior), new propertymetadata(false, onisenabledchanged)); private static void onisenabledchanged(dependencyobject d, dependencypropertychangedeventargs e) { if ((bool) e.newvalue) { var scrollviewer = d scrollviewer; if (scrollviewer != null) { onattached(scrollviewer); } else { throw new notsupportedexception("this behavior supports scrollviewer instances."); } } } private static void onattached(scrollviewer target) { setpageupcanexecutemonitor(target, new pageupcanexecutemonitor(target)); setpagedowncanexecutemonitor(target, new pagedowncanexecutemonitor(target)); } #endregion #region pageupcanexecutemonitor attached property private static void setpageupcanexecutemonitor(dependencyobject obj, pageupcanexecutemonitor value) { obj.setvalue(pageupcanexecutemonitorproperty, value); } private static readonly dependencyproperty pageupcanexecutemonitorproperty = dependencyproperty.registerattached("pageupcanexecutemonitor", typeof (pageupcanexecutemonitor), typeof (scrollbarcommandscanexecutefixbehavior), new propertymetadata(null)); #endregion #region pagedowncanexecutemonitor attached property private static void setpagedowncanexecutemonitor(dependencyobject obj, pagedowncanexecutemonitor value) { obj.setvalue(pagedowncanexecutemonitorproperty, value); } private static readonly dependencyproperty pagedowncanexecutemonitorproperty = dependencyproperty.registerattached("pagedowncanexecutemonitor", typeof (pagedowncanexecutemonitor), typeof (scrollbarcommandscanexecutefixbehavior), new propertymetadata(null)); #endregion }
the basic idea add commandbinding scrollviewer
each of commands , subscribe canexecute
event on bindings. in event handler check current position of scroll , set e.canexecute
property accordingly.
Comments
Post a Comment