none
ScrollBarのRepeatButtonについて RRS feed

  • 質問

  • 現在WPFでアプリケーションを作成しています。

    dataGridなどでデータ数が多い場合にスクロールバーが表示されると思いますが、

    スクロール制御を行うための上下のボタンを非表示にすることはできますでしょうか。

    よろしくお願いいたします。


    2015年8月5日 6:15

回答

  • これも、テンプレートの編集でできそうですね。

    (参考)◆Expanderの角の丸さを変えたい

    https://social.msdn.microsoft.com/Forums/ja-JP/fe180633-025e-4a89-8d49-bcfe6d405e79/expander?forum=wpfja

    ただ、階層が深いので、先にダミープロジェクトとかでScrollBarを配置して「コントロールテンプレートの編集」をし、そのStyleをコピーしてDataGrid等のScrollViewerに参照させる、というやり方になるでしょうね。

    2015年8月5日 7:44
  • 以下のページの、

    Custom ScrollBar Thumb can't be dragged in DataGrid (but RepeatButtons work OK)?
    http://stackoverflow.com/questions/17901383/custom-scrollbar-thumb-cant-be-dragged-in-datagrid-but-repeatbuttons-work-ok

    以下の部分を

    <ControlTemplate x:Key="verScroll" TargetType="ScrollBar">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition MaxHeight="18"/>
                <RowDefinition/>
                <RowDefinition MaxHeight="18"/>
            </Grid.RowDefinitions>

    以下のようにしてみるかですね。

    <ControlTemplate x:Key="verScroll" TargetType="ScrollBar">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="0"/>
                <RowDefinition/>
                <RowDefinition Height="0"/>
            </Grid.RowDefinitions>


    ★良い回答には回答済みマークを付けよう! MVP - .NET  http://d.hatena.ne.jp/trapemiya/

    2015年8月5日 8:08
    モデレータ
  • 普通にやろうとするとテンプレート書き換えだけど、面倒くさいのでテンプレート書き換え無しで非表示にしてみる。

    <Window x:Class="WpfApplication1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:app="clr-namespace:WpfApplication1"
            Title="MainWindow" Height="350" Width="525" >
        <Window.Resources>
            <Style TargetType="{x:Type ScrollBar}">
                <Setter Property="app:ScrollBarTool.Orientation" 
                        Value="{Binding Path=Orientation,RelativeSource={RelativeSource Mode=Self}}" />
            </Style>
        </Window.Resources>
        <Grid>      
            <DataGrid ItemsSource="{Binding}" DataContext="ABCDEFGHIJKLMNOPQRSTUVWXYYZ">
                <DataGrid.Columns>
                    <DataGridTextColumn IsReadOnly="true" Binding="{Binding}" />
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
    </Window>

    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Media;
    using System.Windows.Controls.Primitives;
    
    namespace WpfApplication1
    {
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
        }
    
        class ScrollBarTool
        {
            /// <summary>スクロールバーからリピートボタンを見えなくする</summary>
            /// <param name="sb">対象のスクロールバー</param>
            /// <param name="canRetry">true:ボタンがない(まだ生成されていない)場合にやり直す</param>
            public static void HideScrollBarButton(ScrollBar sb, bool canRetry = true)
            {
                if (sb.Template == null)
                {
                    if (canRetry)
                    {
                        Retry(sb);
                    }
                }
                else
                {
                    if (sb.Orientation == Orientation.Vertical)
                    {
                        if (!HideScrollBarButton(sb, "PART_LineUpButton") || !HideScrollBarButton(sb, "PART_LineDownButton"))
                        {
                            if (canRetry)
                            {
                                Retry(sb);
                            }
                        }
                    }
                    else
                    {
                        if (!HideScrollBarButton(sb, "PART_LineLeftButton") || !HideScrollBarButton(sb, "PART_LineRightButton"))
                        {
                            if (canRetry)
                            {
                                Retry(sb);
                            }
                        }
                    }
                }
            }
            private static void Retry(ScrollBar sb)
            {
                Action<ScrollBar, bool> action = HideScrollBarButton;
                System.Windows.Threading.Dispatcher.CurrentDispatcher.BeginInvoke(action, System.Windows.Threading.DispatcherPriority.Loaded, sb, false);
            }
    
            private static bool HideScrollBarButton(ScrollBar sb, string part)
            {
                var btn = sb.Template.FindName(part, sb) as UIElement;
                if (btn == null)
                {
                    return false;
                }
                if (btn is FrameworkElement)
                {
                    var feButton = (FrameworkElement)btn;
                    feButton.Visibility = System.Windows.Visibility.Collapsed;
                }
                if (VisualTreeHelper.GetParent(btn) is Grid)
                {
                    Grid g = (Grid)VisualTreeHelper.GetParent(btn);
                    int r = Grid.GetRow(btn);
                    int rspan = Grid.GetRowSpan(btn);
                    while (g.RowDefinitions.Count >= r + 1 && rspan > 0)
                    {
                        g.RowDefinitions[r].Height = new GridLength(0);
                        rspan--;
                        r++;
                    }
    
                    int c = Grid.GetColumn(btn);
                    int cspan = Grid.GetColumnSpan(btn);
                    if (g.ColumnDefinitions.Count >= c + 1 && cspan > 0)
                    {
                        g.ColumnDefinitions[c].Width = new GridLength(0);
                        cspan--;
                        c++;
                    }
                }
                return true;
    
            }
    
            #region 向きが変更された時のテンプレート入れかえに対処
    
            /// <summary>向きが変更された場合に検出できるようにする </summary>
            /// <param name="sb"></param>
            public static void SetOrientationTrigger(ScrollBar sb)
            {
                Binding b = new Binding();
                b.Path = new PropertyPath(ScrollBar.OrientationProperty);
                b.Source = sb;
                sb.SetBinding(ScrollBarTool.OrientationProperty, b);
            }
    
            public static Orientation GetOrientation(DependencyObject obj)
            {
                return ( Orientation)obj.GetValue(OrientationProperty);
            }
    
            public static void SetOrientation(DependencyObject obj,  Orientation value)
            {
                obj.SetValue(OrientationProperty, value);
            }
    
            public static readonly DependencyProperty OrientationProperty =
                DependencyProperty.RegisterAttached
                ("Orientation", typeof(Orientation?), typeof(ScrollBarTool)
                , new UIPropertyMetadata(default(Orientation?), new PropertyChangedCallback(OnOrientationPropertyChanged)));
    
            private static void OnOrientationPropertyChanged(DependencyObject dpo, DependencyPropertyChangedEventArgs e)
            {
                ScrollBar sb = dpo as ScrollBar;
                if (sb != null)
                {
                    HideScrollBarButton(sb, true);
                }
            }
    
            #endregion
        }
    }





    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    2015年8月5日 9:00

すべての返信

  • You can't hidden RepeatButton in ScrollBar.

    But I have two solution for you:

    • Use Slider. This similar to  ScrollBar, but without RepeatButton.
    • Set back color transport of ScrollBar, make RepeatButton inconspicuous.

    • 編集済み mosdeo 2015年8月5日 6:50
    2015年8月5日 6:47
  • これも、テンプレートの編集でできそうですね。

    (参考)◆Expanderの角の丸さを変えたい

    https://social.msdn.microsoft.com/Forums/ja-JP/fe180633-025e-4a89-8d49-bcfe6d405e79/expander?forum=wpfja

    ただ、階層が深いので、先にダミープロジェクトとかでScrollBarを配置して「コントロールテンプレートの編集」をし、そのStyleをコピーしてDataGrid等のScrollViewerに参照させる、というやり方になるでしょうね。

    2015年8月5日 7:44
  • 以下のページの、

    Custom ScrollBar Thumb can't be dragged in DataGrid (but RepeatButtons work OK)?
    http://stackoverflow.com/questions/17901383/custom-scrollbar-thumb-cant-be-dragged-in-datagrid-but-repeatbuttons-work-ok

    以下の部分を

    <ControlTemplate x:Key="verScroll" TargetType="ScrollBar">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition MaxHeight="18"/>
                <RowDefinition/>
                <RowDefinition MaxHeight="18"/>
            </Grid.RowDefinitions>

    以下のようにしてみるかですね。

    <ControlTemplate x:Key="verScroll" TargetType="ScrollBar">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="0"/>
                <RowDefinition/>
                <RowDefinition Height="0"/>
            </Grid.RowDefinitions>


    ★良い回答には回答済みマークを付けよう! MVP - .NET  http://d.hatena.ne.jp/trapemiya/

    2015年8月5日 8:08
    モデレータ
  • 普通にやろうとするとテンプレート書き換えだけど、面倒くさいのでテンプレート書き換え無しで非表示にしてみる。

    <Window x:Class="WpfApplication1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:app="clr-namespace:WpfApplication1"
            Title="MainWindow" Height="350" Width="525" >
        <Window.Resources>
            <Style TargetType="{x:Type ScrollBar}">
                <Setter Property="app:ScrollBarTool.Orientation" 
                        Value="{Binding Path=Orientation,RelativeSource={RelativeSource Mode=Self}}" />
            </Style>
        </Window.Resources>
        <Grid>      
            <DataGrid ItemsSource="{Binding}" DataContext="ABCDEFGHIJKLMNOPQRSTUVWXYYZ">
                <DataGrid.Columns>
                    <DataGridTextColumn IsReadOnly="true" Binding="{Binding}" />
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
    </Window>

    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Media;
    using System.Windows.Controls.Primitives;
    
    namespace WpfApplication1
    {
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
        }
    
        class ScrollBarTool
        {
            /// <summary>スクロールバーからリピートボタンを見えなくする</summary>
            /// <param name="sb">対象のスクロールバー</param>
            /// <param name="canRetry">true:ボタンがない(まだ生成されていない)場合にやり直す</param>
            public static void HideScrollBarButton(ScrollBar sb, bool canRetry = true)
            {
                if (sb.Template == null)
                {
                    if (canRetry)
                    {
                        Retry(sb);
                    }
                }
                else
                {
                    if (sb.Orientation == Orientation.Vertical)
                    {
                        if (!HideScrollBarButton(sb, "PART_LineUpButton") || !HideScrollBarButton(sb, "PART_LineDownButton"))
                        {
                            if (canRetry)
                            {
                                Retry(sb);
                            }
                        }
                    }
                    else
                    {
                        if (!HideScrollBarButton(sb, "PART_LineLeftButton") || !HideScrollBarButton(sb, "PART_LineRightButton"))
                        {
                            if (canRetry)
                            {
                                Retry(sb);
                            }
                        }
                    }
                }
            }
            private static void Retry(ScrollBar sb)
            {
                Action<ScrollBar, bool> action = HideScrollBarButton;
                System.Windows.Threading.Dispatcher.CurrentDispatcher.BeginInvoke(action, System.Windows.Threading.DispatcherPriority.Loaded, sb, false);
            }
    
            private static bool HideScrollBarButton(ScrollBar sb, string part)
            {
                var btn = sb.Template.FindName(part, sb) as UIElement;
                if (btn == null)
                {
                    return false;
                }
                if (btn is FrameworkElement)
                {
                    var feButton = (FrameworkElement)btn;
                    feButton.Visibility = System.Windows.Visibility.Collapsed;
                }
                if (VisualTreeHelper.GetParent(btn) is Grid)
                {
                    Grid g = (Grid)VisualTreeHelper.GetParent(btn);
                    int r = Grid.GetRow(btn);
                    int rspan = Grid.GetRowSpan(btn);
                    while (g.RowDefinitions.Count >= r + 1 && rspan > 0)
                    {
                        g.RowDefinitions[r].Height = new GridLength(0);
                        rspan--;
                        r++;
                    }
    
                    int c = Grid.GetColumn(btn);
                    int cspan = Grid.GetColumnSpan(btn);
                    if (g.ColumnDefinitions.Count >= c + 1 && cspan > 0)
                    {
                        g.ColumnDefinitions[c].Width = new GridLength(0);
                        cspan--;
                        c++;
                    }
                }
                return true;
    
            }
    
            #region 向きが変更された時のテンプレート入れかえに対処
    
            /// <summary>向きが変更された場合に検出できるようにする </summary>
            /// <param name="sb"></param>
            public static void SetOrientationTrigger(ScrollBar sb)
            {
                Binding b = new Binding();
                b.Path = new PropertyPath(ScrollBar.OrientationProperty);
                b.Source = sb;
                sb.SetBinding(ScrollBarTool.OrientationProperty, b);
            }
    
            public static Orientation GetOrientation(DependencyObject obj)
            {
                return ( Orientation)obj.GetValue(OrientationProperty);
            }
    
            public static void SetOrientation(DependencyObject obj,  Orientation value)
            {
                obj.SetValue(OrientationProperty, value);
            }
    
            public static readonly DependencyProperty OrientationProperty =
                DependencyProperty.RegisterAttached
                ("Orientation", typeof(Orientation?), typeof(ScrollBarTool)
                , new UIPropertyMetadata(default(Orientation?), new PropertyChangedCallback(OnOrientationPropertyChanged)));
    
            private static void OnOrientationPropertyChanged(DependencyObject dpo, DependencyPropertyChangedEventArgs e)
            {
                ScrollBar sb = dpo as ScrollBar;
                if (sb != null)
                {
                    HideScrollBarButton(sb, true);
                }
            }
    
            #endregion
        }
    }





    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    2015年8月5日 9:00
  • 皆様

    返信を頂きありがとうございました。

    今のところテンプレートの編集の方法を使用し、自分の期待通りの表示にすることができました。

    ありがとうございました。

    2015年8月7日 4:43