WPFで、Listboxを用い、その中にボタンを配置した時のタッチ操作です。
どうも操作感がイマイチで、Clickイベントが発生する場合と発生しない場合があります。タッチの仕方によって、Listboxの行が選択されたようになります。
こちらに質問したら、親切に教えていただけました。ほんと助かります。
https://social.msdn.microsoft.com/Forums/ja-JP/eec04319-4e9c-43b8-b0fd-35e00515de66/listbox-?forum=wpfja&prof=required
Listboxの上でタッチする際に、指が少しでも動いてしまうと、スワイプしたような状態になりClickイベントが発生せず、TouchUpとかその他のイベントが発生して、行選択状態になるようです。教えていただいたコードとしては、
目次
Xaml上で プレス&ホールド(長押し)動作を無視する
https://msdn.microsoft.com/ja-jp/library/system.windows.input.stylus.ispressandholdenabled(v=vs.110).aspx
プレス アンド ホールドは、マウスの右クリックにマップされます。Windows Vista では、ユーザーがタブレット ペンを押したままにする可能性があり、右クリックをシミュレートする必要のない要素上では、この動作を無効にできます。
l_listbox_PreviewTouchMoveを無効にする
1 2 3 4 |
private void l_listbox_PreviewTouchMove(object sender, TouchEventArgs e) { e.Handled = true;//ホットトラックを無効に } |
http://www.atmarkit.co.jp/ait/articles/0411/19/news111.html
「e」のHandledプロパティは、イベントを処理したかどうかを設定するためのもの
HandledプロパティにTrueを設定している。これにより、コントロール側のKeyDownイベント・ハンドラは呼び出されなくなる
https://msdn.microsoft.com/ja-jp/library/ms754010(v=vs.110).aspx
ユーザーがその要素内で指を移動すると、それに従って TouchMove イベントが複数回発生します。
previewイベント
https://msdn.microsoft.com/ja-jp/library/ms752279(v=vs.110).aspx
プレビュー イベントはトンネル イベントとも呼ばれ、アプリケーション ルートから、イベントの発生元でありイベント データでソースとして報告される要素へ向かって経路をたどるルーティング イベントです。
特定のイベントがコントロールから生成されるのを抑制し、コンポーネントで定義された別のイベント (より多くの情報を含むイベントや、より具体的な動作を表すイベント) に置き換える場合もあります。
バブルイベントが、イベントの発生元から親要素・親要素…へ伝搬していくのに対して、トンネルイベントはルートの要素からイベント発生元のオブジェクトの順番でイベントが伝搬していきます。(ちょうどトンネルイベントの逆の動きになります)
ルーティングイベントは、RoutedEventArgsのHandledプロパティをtrueにすることで、後続のイベントをキャンセルすることが出来ます。この機能を使うと、トンネルイベントやバブルイベントを途中でインターセプトして後続のイベントの処理をキャンセルすることが出来ます。
親を探せ
1 2 3 4 5 6 7 8 9 10 11 12 |
private T FindParent<T>(DependencyObject d) where T : DependencyObject { while (d != null) { d = VisualTreeHelper.GetParent(d); if (d is T) { return (T)d; } } return null; } |
previewTouchDownへの処理
1 2 3 4 5 6 7 8 9 10 11 12 |
private void B_test_PreviewTouchDown(object sender, TouchEventArgs e) { e.TouchDevice.Capture((Button)sender);//ボタンから外れても大丈夫なようにキャプチャする Button btn = (Button)sender; btn.TouchUp += Button_TouchUp; e.Handled = true; //タッチポインタが動いても他のListBoxItemにホットトラックされないようにする ListBox listBox = FindParent<ListBox>(btn); listBox.PreviewTouchMove += l_listbox_PreviewTouchMove; } |
TouchDevice.Capture メソッド
https://msdn.microsoft.com/ja-jp/library/dd989302(v=vs.110).aspx
指定した要素へのタッチをキャプチャします。
タッチイベントのcaptureについて
https://code.msdn.microsoft.com/windowsdesktop/CVBXAML-WPF-4-TouchDown-b1018a60
capture ⇒ 捉える、補足する
そのイベントが他に流れないように補足する事(かな?)
TouchDownイベントが発生したら、TouchUpイベントを発生させる。
TouchDeviceのイベントをキャプチャして他に流れないようにする。
ModelParent.FindParent メソッド
https://msdn.microsoft.com/ja-jp/library/microsoft.windows.design.model.modelparent.findparent(v=vs.90).aspx
指定した子の型に対して有効な親を検索します。
ボタンの親のListboxを特定して、listbox_PreviewTouchMoveを故意に発生させ、実態はe.Handled = true で処理をキャンセルする
Button_TouchUPで後処理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
private void Button_TouchUp(object sender, TouchEventArgs e) { Button btn = (Button)sender; btn.TouchUp -= Button_TouchUp; ListBox listBox = FindParent<ListBox>(btn); listBox.PreviewTouchMove -= l_listbox_PreviewTouchMove; e.TouchDevice.Capture(null);//キャプチャ解除 //クリックイベントを作る var rev = new RoutedEventArgs(Button.ClickEvent); btn.RaiseEvent(rev); //クリックイベント生成 e.Handled = true;//元のクリックイベントが発生しないようにする } |
ボタンのタッチアップイベントを処分
リストボックスのPreviewTouchMoveイベントを処分
キャプターを解除する。
クリックイベントを発生させ、もともと、TouchEventArgsに入っていたイベントはキャンセルする。
○Xaml全貌
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 |
<Window x:Class="SliderThumb.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:SliderThumb" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525"> <Window.Resources> <SolidColorBrush x:Key="SliderThumb.Static.Foreground" Color="#FFE5E5E5"/> <SolidColorBrush x:Key="SliderThumb.MouseOver.Background" Color="#FFDCECFC"/> <SolidColorBrush x:Key="SliderThumb.MouseOver.Border" Color="#FF7Eb4EA"/> <SolidColorBrush x:Key="SliderThumb.Pressed.Background" Color="#FFDAECFC"/> <SolidColorBrush x:Key="SliderThumb.Pressed.Border" Color="#FF569DE5"/> <SolidColorBrush x:Key="SliderThumb.Disabled.Background" Color="#FFF0F0F0"/> <SolidColorBrush x:Key="SliderThumb.Disabled.Border" Color="#FFD9D9D9"/> <SolidColorBrush x:Key="SliderThumb.Static.Background" Color="#FFF0F0F0"/> <SolidColorBrush x:Key="SliderThumb.Static.Border" Color="#FFACACAC"/> <ControlTemplate x:Key="SliderThumbHorizontalTop" TargetType="{x:Type Thumb}"> <Grid HorizontalAlignment="Center" UseLayoutRounding="True" VerticalAlignment="Center"> <Path x:Name="grip" Data="M 0,6 C0,6 5.5,0 5.5,0 5.5,0 11,6 11,6 11,6 11,18 11,18 11,18 0,18 0,18 0,18 0,6 0,6 z" Fill="{StaticResource SliderThumb.Static.Background}" Stretch="Fill" SnapsToDevicePixels="True" Stroke="{StaticResource SliderThumb.Static.Border}" StrokeThickness="1" UseLayoutRounding="True" VerticalAlignment="Center"/> </Grid> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="true"> <Setter Property="Fill" TargetName="grip" Value="{StaticResource SliderThumb.MouseOver.Background}"/> <Setter Property="Stroke" TargetName="grip" Value="{StaticResource SliderThumb.MouseOver.Border}"/> </Trigger> <Trigger Property="IsDragging" Value="true"> <Setter Property="Fill" TargetName="grip" Value="{StaticResource SliderThumb.Pressed.Background}"/> <Setter Property="Stroke" TargetName="grip" Value="{StaticResource SliderThumb.Pressed.Border}"/> </Trigger> <Trigger Property="IsEnabled" Value="false"> <Setter Property="Fill" TargetName="grip" Value="{StaticResource SliderThumb.Disabled.Background}"/> <Setter Property="Stroke" TargetName="grip" Value="{StaticResource SliderThumb.Disabled.Border}"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> <ControlTemplate x:Key="SliderThumbHorizontalBottom" TargetType="{x:Type Thumb}"> <Grid HorizontalAlignment="Center" UseLayoutRounding="True" VerticalAlignment="Center"> <Path x:Name="grip" Data="M 0,12 C0,12 5.5,18 5.5,18 5.5,18 11,12 11,12 11,12 11,0 11,0 11,0 0,0 0,0 0,0 0,12 0,12 z" Fill="{StaticResource SliderThumb.Static.Background}" Stretch="Fill" SnapsToDevicePixels="True" Stroke="{StaticResource SliderThumb.Static.Border}" StrokeThickness="1" UseLayoutRounding="True" VerticalAlignment="Center"/> </Grid> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="true"> <Setter Property="Fill" TargetName="grip" Value="{StaticResource SliderThumb.MouseOver.Background}"/> <Setter Property="Stroke" TargetName="grip" Value="{StaticResource SliderThumb.MouseOver.Border}"/> </Trigger> <Trigger Property="IsDragging" Value="true"> <Setter Property="Fill" TargetName="grip" Value="{StaticResource SliderThumb.Pressed.Background}"/> <Setter Property="Stroke" TargetName="grip" Value="{StaticResource SliderThumb.Pressed.Border}"/> </Trigger> <Trigger Property="IsEnabled" Value="false"> <Setter Property="Fill" TargetName="grip" Value="{StaticResource SliderThumb.Disabled.Background}"/> <Setter Property="Stroke" TargetName="grip" Value="{StaticResource SliderThumb.Disabled.Border}"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> <SolidColorBrush x:Key="SliderThumb.Track.Border" Color="#FFD6D6D6"/> <SolidColorBrush x:Key="SliderThumb.Track.Background" Color="#FFE7EAEA"/> <Style x:Key="RepeatButtonTransparent" TargetType="{x:Type RepeatButton}"> <Setter Property="OverridesDefaultStyle" Value="true"/> <Setter Property="Background" Value="Transparent"/> <Setter Property="Focusable" Value="false"/> <Setter Property="IsTabStop" Value="false"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type RepeatButton}"> <Rectangle Fill="#FF5757B9" Margin="0,5.5" Width="4.5"/> </ControlTemplate> </Setter.Value> </Setter> </Style> <ControlTemplate x:Key="SliderThumbHorizontalDefault" TargetType="{x:Type Thumb}"> <Grid HorizontalAlignment="Center" UseLayoutRounding="True" VerticalAlignment="Center"> <Path x:Name="grip" Data="M 0,0 C0,0 11,0 11,0 11,0 11,18 11,18 11,18 0,18 0,18 0,18 0,0 0,0 z" Fill="{StaticResource SliderThumb.Static.Background}" Stretch="Fill" SnapsToDevicePixels="True" Stroke="{StaticResource SliderThumb.Static.Border}" StrokeThickness="1" UseLayoutRounding="True" VerticalAlignment="Center"/> </Grid> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="true"> <Setter Property="Fill" TargetName="grip" Value="{StaticResource SliderThumb.MouseOver.Background}"/> <Setter Property="Stroke" TargetName="grip" Value="{StaticResource SliderThumb.MouseOver.Border}"/> </Trigger> <Trigger Property="IsDragging" Value="true"> <Setter Property="Fill" TargetName="grip" Value="{StaticResource SliderThumb.Pressed.Background}"/> <Setter Property="Stroke" TargetName="grip" Value="{StaticResource SliderThumb.Pressed.Border}"/> </Trigger> <Trigger Property="IsEnabled" Value="false"> <Setter Property="Fill" TargetName="grip" Value="{StaticResource SliderThumb.Disabled.Background}"/> <Setter Property="Stroke" TargetName="grip" Value="{StaticResource SliderThumb.Disabled.Border}"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> <ControlTemplate x:Key="SliderHorizontal" TargetType="{x:Type Slider}"> <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto" MinHeight="{TemplateBinding MinHeight}"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <TickBar x:Name="TopTick" Fill="{TemplateBinding Foreground}" Height="4" Margin="0,0,0,2" Placement="Top" Grid.Row="0" Visibility="Collapsed"/> <TickBar x:Name="BottomTick" Fill="{TemplateBinding Foreground}" Height="4" Margin="0,2,0,0" Placement="Bottom" Grid.Row="2" Visibility="Collapsed"/> <Border x:Name="TrackBackground" BorderBrush="{StaticResource SliderThumb.Track.Border}" BorderThickness="1" Background="{StaticResource SliderThumb.Track.Background}" Height="4.0" Margin="5,0" Grid.Row="1" VerticalAlignment="center"> <Canvas Margin="-6,-1"> <Rectangle x:Name="PART_SelectionRange" Fill="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" Height="4.0" Visibility="Hidden"/> </Canvas> </Border> <Track x:Name="PART_Track" Grid.Row="1"> <Track.DecreaseRepeatButton> <RepeatButton Command="{x:Static Slider.DecreaseLarge}" Style="{StaticResource RepeatButtonTransparent}"/> </Track.DecreaseRepeatButton> <Track.IncreaseRepeatButton> <RepeatButton Command="{x:Static Slider.IncreaseLarge}" Style="{StaticResource RepeatButtonTransparent}"/> </Track.IncreaseRepeatButton> <Track.Thumb> <Thumb x:Name="Thumb" Focusable="False" Height="18" OverridesDefaultStyle="True" Template="{StaticResource SliderThumbHorizontalDefault}" VerticalAlignment="Center" Width="11"/> </Track.Thumb> </Track> </Grid> </Border> <ControlTemplate.Triggers> <Trigger Property="TickPlacement" Value="TopLeft"> <Setter Property="Visibility" TargetName="TopTick" Value="Visible"/> <Setter Property="Template" TargetName="Thumb" Value="{StaticResource SliderThumbHorizontalTop}"/> <Setter Property="Margin" TargetName="TrackBackground" Value="5,2,5,0"/> </Trigger> <Trigger Property="TickPlacement" Value="BottomRight"> <Setter Property="Visibility" TargetName="BottomTick" Value="Visible"/> <Setter Property="Template" TargetName="Thumb" Value="{StaticResource SliderThumbHorizontalBottom}"/> <Setter Property="Margin" TargetName="TrackBackground" Value="5,0,5,2"/> </Trigger> <Trigger Property="TickPlacement" Value="Both"> <Setter Property="Visibility" TargetName="TopTick" Value="Visible"/> <Setter Property="Visibility" TargetName="BottomTick" Value="Visible"/> </Trigger> <Trigger Property="IsSelectionRangeEnabled" Value="true"> <Setter Property="Visibility" TargetName="PART_SelectionRange" Value="Visible"/> </Trigger> <Trigger Property="IsKeyboardFocused" Value="true"> <Setter Property="Foreground" TargetName="Thumb" Value="Blue"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> <ControlTemplate x:Key="SliderThumbVerticalLeft" TargetType="{x:Type Thumb}"> <Grid HorizontalAlignment="Center" UseLayoutRounding="True" VerticalAlignment="Center"> <Path x:Name="grip" Data="M 6,11 C6,11 0,5.5 0,5.5 0,5.5 6,0 6,0 6,0 18,0 18,0 18,0 18,11 18,11 18,11 6,11 6,11 z" Fill="{StaticResource SliderThumb.Static.Background}" Stretch="Fill" Stroke="{StaticResource SliderThumb.Static.Border}"/> </Grid> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="true"> <Setter Property="Fill" TargetName="grip" Value="{StaticResource SliderThumb.MouseOver.Background}"/> <Setter Property="Stroke" TargetName="grip" Value="{StaticResource SliderThumb.MouseOver.Border}"/> </Trigger> <Trigger Property="IsDragging" Value="true"> <Setter Property="Fill" TargetName="grip" Value="{StaticResource SliderThumb.Pressed.Background}"/> <Setter Property="Stroke" TargetName="grip" Value="{StaticResource SliderThumb.Pressed.Border}"/> </Trigger> <Trigger Property="IsEnabled" Value="false"> <Setter Property="Fill" TargetName="grip" Value="{StaticResource SliderThumb.Disabled.Background}"/> <Setter Property="Stroke" TargetName="grip" Value="{StaticResource SliderThumb.Disabled.Border}"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> <ControlTemplate x:Key="SliderThumbVerticalRight" TargetType="{x:Type Thumb}"> <Grid HorizontalAlignment="Center" UseLayoutRounding="True" VerticalAlignment="Center"> <Path x:Name="grip" Data="M 12,11 C12,11 18,5.5 18,5.5 18,5.5 12,0 12,0 12,0 0,0 0,0 0,0 0,11 0,11 0,11 12,11 12,11 z" Fill="{StaticResource SliderThumb.Static.Background}" Stretch="Fill" Stroke="{StaticResource SliderThumb.Static.Border}"/> </Grid> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="true"> <Setter Property="Fill" TargetName="grip" Value="{StaticResource SliderThumb.MouseOver.Background}"/> <Setter Property="Stroke" TargetName="grip" Value="{StaticResource SliderThumb.MouseOver.Border}"/> </Trigger> <Trigger Property="IsDragging" Value="true"> <Setter Property="Fill" TargetName="grip" Value="{StaticResource SliderThumb.Pressed.Background}"/> <Setter Property="Stroke" TargetName="grip" Value="{StaticResource SliderThumb.Pressed.Border}"/> </Trigger> <Trigger Property="IsEnabled" Value="false"> <Setter Property="Fill" TargetName="grip" Value="{StaticResource SliderThumb.Disabled.Background}"/> <Setter Property="Stroke" TargetName="grip" Value="{StaticResource SliderThumb.Disabled.Border}"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> <ControlTemplate x:Key="SliderThumbVerticalDefault" TargetType="{x:Type Thumb}"> <Grid HorizontalAlignment="Center" UseLayoutRounding="True" VerticalAlignment="Center"> <Path x:Name="grip" Data="M0.5,0.5 L18.5,0.5 18.5,11.5 0.5,11.5z" Fill="{StaticResource SliderThumb.Static.Background}" Stretch="Fill" Stroke="{StaticResource SliderThumb.Static.Border}"/> </Grid> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="true"> <Setter Property="Fill" TargetName="grip" Value="{StaticResource SliderThumb.MouseOver.Background}"/> <Setter Property="Stroke" TargetName="grip" Value="{StaticResource SliderThumb.MouseOver.Border}"/> </Trigger> <Trigger Property="IsDragging" Value="true"> <Setter Property="Fill" TargetName="grip" Value="{StaticResource SliderThumb.Pressed.Background}"/> <Setter Property="Stroke" TargetName="grip" Value="{StaticResource SliderThumb.Pressed.Border}"/> </Trigger> <Trigger Property="IsEnabled" Value="false"> <Setter Property="Fill" TargetName="grip" Value="{StaticResource SliderThumb.Disabled.Background}"/> <Setter Property="Stroke" TargetName="grip" Value="{StaticResource SliderThumb.Disabled.Border}"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> <ControlTemplate x:Key="SliderVertical" TargetType="{x:Type Slider}"> <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True"> <Grid Margin="10,0,0,0"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition MinWidth="{TemplateBinding MinWidth}" Width="Auto"/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <TickBar x:Name="TopTick" Grid.Column="0" Fill="{TemplateBinding Foreground}" Margin="0,0,2,0" Placement="Left" Visibility="Collapsed" Width="4"/> <TickBar x:Name="BottomTick" Grid.Column="2" Fill="{TemplateBinding Foreground}" Margin="2,0,0,0" Placement="Right" Visibility="Collapsed" Width="4"/> <Border x:Name="TrackBackground" BorderBrush="{StaticResource SliderThumb.Track.Border}" BorderThickness="1" Background="{StaticResource SliderThumb.Track.Background}" Grid.Column="1" HorizontalAlignment="center" Margin="0,5" Width="4.0"> <Canvas Margin="-1,-6"> <Rectangle x:Name="PART_SelectionRange" Fill="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" Visibility="Hidden" Width="4.0"/> </Canvas> </Border> <Track x:Name="PART_Track" Grid.Column="1"> <Track.DecreaseRepeatButton> <RepeatButton Command="{x:Static Slider.DecreaseLarge}" Style="{StaticResource RepeatButtonTransparent}"/> </Track.DecreaseRepeatButton> <Track.IncreaseRepeatButton> <RepeatButton Command="{x:Static Slider.IncreaseLarge}" Style="{StaticResource RepeatButtonTransparent}" Height="288" VerticalAlignment="Bottom"/> </Track.IncreaseRepeatButton> <Track.Thumb> <Thumb x:Name="Thumb" Focusable="False" Height="48.009" OverridesDefaultStyle="True" Template="{DynamicResource ThumbControlTemplate1}" VerticalAlignment="Top" Width="Auto" FocusVisualStyle="{DynamicResource ControlStyle1}" Margin="-20.091,0,-23.263,-37.009"/> </Track.Thumb> </Track> <Rectangle Grid.ColumnSpan="1" Grid.Column="2" Fill="#FF5757B9" HorizontalAlignment="Right" Height="0" Margin="0,68,-380,0" VerticalAlignment="Top" Width="4"/> </Grid> </Border> <ControlTemplate.Triggers> <Trigger Property="TickPlacement" Value="TopLeft"> <Setter Property="Visibility" TargetName="TopTick" Value="Visible"/> <Setter Property="Template" TargetName="Thumb" Value="{StaticResource SliderThumbVerticalLeft}"/> <Setter Property="Margin" TargetName="TrackBackground" Value="2,5,0,5"/> </Trigger> <Trigger Property="TickPlacement" Value="BottomRight"> <Setter Property="Visibility" TargetName="BottomTick" Value="Visible"/> <Setter Property="Template" TargetName="Thumb" Value="{StaticResource SliderThumbVerticalRight}"/> <Setter Property="Margin" TargetName="TrackBackground" Value="0,5,2,5"/> </Trigger> <Trigger Property="TickPlacement" Value="Both"> <Setter Property="Visibility" TargetName="TopTick" Value="Visible"/> <Setter Property="Visibility" TargetName="BottomTick" Value="Visible"/> </Trigger> <Trigger Property="IsSelectionRangeEnabled" Value="true"> <Setter Property="Visibility" TargetName="PART_SelectionRange" Value="Visible"/> </Trigger> <Trigger Property="IsKeyboardFocused" Value="true"> <Setter Property="Foreground" TargetName="Thumb" Value="Blue"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> <Style x:Key="SliderStyle1" TargetType="{x:Type Slider}"> <Setter Property="Stylus.IsPressAndHoldEnabled" Value="false"/> <Setter Property="Background" Value="Transparent"/> <Setter Property="BorderBrush" Value="Transparent"/> <Setter Property="Foreground" Value="{StaticResource SliderThumb.Static.Foreground}"/> <Setter Property="Template" Value="{StaticResource SliderHorizontal}"/> <Style.Triggers> <Trigger Property="Orientation" Value="Vertical"> <Setter Property="Template" Value="{StaticResource SliderVertical}"/> </Trigger> </Style.Triggers> </Style> <Style x:Key="ControlStyle1" TargetType="{x:Type Control}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type Control}"> <Grid> <Ellipse Stroke="Black"> <Ellipse.Fill> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="#FF030A32" Offset="0"/> <GradientStop Color="#FF222853" Offset="1"/> </LinearGradientBrush> </Ellipse.Fill> </Ellipse> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> <ControlTemplate x:Key="ThumbControlTemplate1" TargetType="{x:Type Thumb}"> <Ellipse Margin="0,0,1.333,3.35" Stroke="Black"> <Ellipse.Fill> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="#FF030A32" Offset="0"/> <GradientStop Color="#FF767CA6" Offset="1"/> </LinearGradientBrush> </Ellipse.Fill> </Ellipse> </ControlTemplate> </Window.Resources> <Grid> <Slider x:Name="slider" HorizontalAlignment="Left" Margin="229,10,0,0" VerticalAlignment="Top" Height="299" Width="31" ValueChanged="slider_ValueChanged" Orientation="Vertical" IsDirectionReversed="True" Style="{DynamicResource SliderStyle1}" FocusVisualStyle="{DynamicResource ControlStyle1}"/> <TextBox x:Name="SliderValue" HorizontalAlignment="Left" Height="23" Margin="287,23,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="201"/> <Button x:Name="button" Content="上げる" HorizontalAlignment="Left" Margin="287,81,0,0" VerticalAlignment="Top" Width="75" Click="button_Click"/> <Button x:Name="button_Copy" Content="下げる" HorizontalAlignment="Left" Margin="413,81,0,0" VerticalAlignment="Top" Width="75" Click="button_Copy_Click"/> <ListBox x:Name="l_listbox" HorizontalAlignment="Left" Height="309" Margin="0,10,0,0" VerticalAlignment="Top" Width="220" BorderThickness="0" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Disabled" PreviewTouchMove="l_listbox_PreviewTouchMove"> <ListBox.ItemsPanel> <ItemsPanelTemplate> <StackPanel Orientation="Vertical"/> </ItemsPanelTemplate> </ListBox.ItemsPanel> <ListBox.ItemTemplate> <DataTemplate> <Grid Width="210" Height="60" > <Button x:Name="B_test" Tag="{Binding}" Content="{Binding ButtonContent}" Height="60" Margin="1,-5,0,0" FontSize="29" FontWeight="Bold" Width="220" Foreground="#FFFFFFFF" HorizontalAlignment="Left" Click="B_test_Click" Stylus.IsPressAndHoldEnabled="False" PreviewTouchDown="B_test_PreviewTouchDown"> <Button.Effect> <DropShadowEffect/> </Button.Effect> <Button.Background> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="#FF46AF0E" Offset="0"/> <GradientStop Color="White" Offset="1"/> </LinearGradientBrush> </Button.Background> </Button> </Grid> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </Grid> </Window> |
○C#コード全貌
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.Windows.Automation.Peers; using System.Windows.Automation.Provider; namespace SliderThumb { /// <summary> /// MainWindow.xaml の相互作用ロジック /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); List<TestItem> items = new List<TestItem>(); for (int i = 0; i < 30; i++) { items.Add(new TestItem(i + ":Test")); } l_listbox.ItemsSource = items; slider.Maximum = 30; } private void slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) { SliderValue.Text = slider.Value.ToString(); l_listbox.SelectedIndex = (int)slider.Value; double scrollpoint = slider.Value / 30 * 100; // ListBoxからAutomationPeerを取得 var peer = ItemsControlAutomationPeer.CreatePeerForElement(this.l_listbox); // GetPatternでIScrollProviderを取得 var scrollProvider = peer.GetPattern(PatternInterface.Scroll) as IScrollProvider; // パーセントで位置を指定してスクロール scrollProvider.SetScrollPercent( // 水平スクロールは今の位置 scrollProvider.HorizontalScrollPercent, // スクロール位置を割合で指定する scrollpoint); } private void button_Click(object sender, RoutedEventArgs e) { slider.Value = slider.Value + 1; } private void button_Copy_Click(object sender, RoutedEventArgs e) { slider.Value = slider.Value - 1; } public class TestItem { public String ButtonContent { get; set; } public TestItem(String button_name) { this.ButtonContent = button_name; } } private void B_test_Click(object sender, RoutedEventArgs e) { var o = (TestItem)((Button)sender).Tag; MessageBox.Show(o.ButtonContent.ToString()); System.Windows.Input.Keyboard.ClearFocus(); } private void B_test_PreviewTouchDown(object sender, TouchEventArgs e) { e.TouchDevice.Capture((Button)sender);//ボタンから外れても大丈夫なようにキャプチャする Button btn = (Button)sender; btn.TouchUp += Button_TouchUp; e.Handled = true; //タッチポインタが動いても他のListBoxItemにホットトラックされないようにする ListBox listBox = FindParent<ListBox>(btn); listBox.PreviewTouchMove += l_listbox_PreviewTouchMove; } private void Button_TouchUp(object sender, TouchEventArgs e) { Button btn = (Button)sender; btn.TouchUp -= Button_TouchUp; ListBox listBox = FindParent<ListBox>(btn); listBox.PreviewTouchMove -= l_listbox_PreviewTouchMove; e.TouchDevice.Capture(null);//キャプチャ解除 //クリックイベントを作る var rev = new RoutedEventArgs(Button.ClickEvent); btn.RaiseEvent(rev); //クリックイベント生成 e.Handled = true;//元のクリックイベントが発生しないようにする } private T FindParent<T>(DependencyObject d) where T : DependencyObject { while (d != null) { d = VisualTreeHelper.GetParent(d); if (d is T) { return (T)d; } } return null; } private void l_listbox_PreviewTouchMove(object sender, TouchEventArgs e) { e.Handled = true;//ホットトラックを無効に } } } |