2011-01-25 144 views
3

我正在製作使用列表框的觸摸屏界面。
我有一個按鈕上方和下方的頁面向上/向下翻頁。當滾動到頂部/底部Wpf禁用重複按鈕

我試圖讓它到達滾動頁面按鈕被禁用時的所有位置。
並且一直向下滾動頁面下拉按鈕時也會被禁用。

這裏有一個列表框

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

在我Styles.xaml代碼這裏的地方我實例

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

回答

2

只需使用PageUpCommand爲的CanExecute方法。返回false如果沒有剩餘頁面,按鈕將自動變爲禁用狀態。

編輯:

我創建了一個簡單的attached behavior可以用來解決這個問題。剛剛成立的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 
} 

的基本想法是,我們添加了一個CommandBindingScrollViewer爲每個命令並訂閱這些綁定上的CanExecute事件。在事件處理程序中,我們檢查滾動的當前位置並相應地設置e.CanExecute屬性。

+0

非常好。完美的作品。 我必須禁用LIneLeft和LineRight按鈕,並稍作更改才能按預期工作。 謝謝! – 2015-06-01 12:43:31

相關問題