当滚动到顶部/底部时,Wpf禁用重复按钮

时间:2011-01-25 15:07:31

标签: wpf xaml listbox repeatbutton

我正在制作一个使用列表框的触摸屏界面 我在列表框的上方和下方有一个按钮,用于向上/向下翻页。

我正试图将它向上滚动,一直向上滚动页面按钮被禁用 当向下滚动时,向下翻页按钮也会被禁用。

以下是我的Styles.xaml中列表框的代码

<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> 

这是我实例化列表框的地方

<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> 

我昨天四处搜寻,没有运气 我希望能够在xaml中完成所有工作。

我正在使用按钮的图像,但为了上述可读性而将它们拿出来,
他们真的很像......

<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>

1 个答案:

答案 0 :(得分:2)

只需使用CanExecute的{​​{1}}方法即可。如果没有页面,则返回PageUpCommand,该按钮将自动禁用。

修改

我创建了一个简单的attached behavior,可以用来解决这个问题。只需在false上设置以下附加属性:

ScrollViewer

以下是行为的源代码:

<ScrollViewer x:Name="scrollviewer"
              z:ScrollBarCommandsCanExecuteFixBehavior.IsEnabled="True">  
     <ItemsPresenter/>  
</ScrollViewer> 

基本思想是我们为每个命令的public static class ScrollBarCommandsCanExecuteFixBehavior { #region Nested Types public class CommandCanExecuteMonitor<T> where 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 as ScrollViewer; if (scrollViewer != null) { OnAttached(scrollViewer); } else { throw new NotSupportedException("This behavior only 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 } 添加CommandBinding,并在这些绑定上订阅CanExecute事件。在事件处理程序中,我们检查滚动的当前位置并相应地设置ScrollViewer属性。