none
WPF Win8 タッチパネルでのDataGrid 複数選択 RRS feed

  • 質問

  • 現在WPFでアプリケーションを作成しており、タブレットなどで使用することを考えています。

    DataGridの行を複数選択したいと思ったのですが、タブレットの際はどうすればよいのかいろいろと調べていき、

    スクリーンキーボードを複数選択をするために使用するという方法なども見つけましたが、できればソフトのなかでカバーできればと思います。

    ですので、DataGridの行をクリックするだけで複数選択を可能(選択したものをもう一度選択すると非選択状態に)するようにできますでしょうか。

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

    2015年8月11日 12:31

回答

    • 回答としてマーク 星 睦美 2015年8月17日 1:57
    2015年8月11日 13:22
  • こんな?

    <Window x:Class="WpfApplication1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Window.Resources>
    
            <Style TargetType="{x:Type DataGridCell}">
                <EventSetter Event="PreviewMouseLeftButtonDown"
                             Handler="cell_PreviewMouseLeftButtonDown" />
    
                <EventSetter Event="PreviewTouchDown"
                             Handler="cell_PreviewTouchDown" />
            </Style>
            <Style TargetType="{x:Type DataGridRowHeader}">
                <EventSetter Event="PreviewMouseLeftButtonDown"
                             Handler="cell_PreviewMouseLeftButtonDown" />
    
                <EventSetter Event="PreviewTouchDown"
                             Handler="cell_PreviewTouchDown" />
            </Style>
        </Window.Resources>
    
        <DataGrid ItemsSource="{Binding}" DataContext="ABCDEFGHIJKLMNOPQRSTUVWXYZ" RowHeaderWidth="50" TextElement.FontSize="30" >
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding}" IsReadOnly="true" Header="Test" Width="100"/>
                <DataGridTextColumn Binding="{Binding}" IsReadOnly="true" Header="Test" Width="100"/>
            </DataGrid.Columns>
        </DataGrid>
    
    </Window>
    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Controls.Primitives;
    namespace WpfApplication1
    {
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
            bool isTouch = false;
            private void cell_PreviewTouchDown(object sender, TouchEventArgs e)
            {
                Test(sender);
                e.Handled = true;
                isTouch = true;
            }
    
            void cell_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                //TouchイベントをHandled=trueしてもMouseイベントも発生してしまうので
                //Touchイベントの後はマウスイベントの処理を阻止
                e.Handled = isTouch;
                isTouch = false;
    
                Test(sender);
            }
            private void Test(object sender)
            {
                DataGridRowHeader header = sender as DataGridRowHeader;
                DataGridCell cell = sender as DataGridCell;
                DependencyObject d = cell ?? (DependencyObject)header;
                DataGridRow row = null;
                DataGrid dg = null;
                while (d != null && row == null)
                {
                    row = d as DataGridRow;
                    d = VisualTreeHelper.GetParent(d);
                }
                while (d != null && dg == null)
                {
                    dg = d as DataGrid;
                    d = VisualTreeHelper.GetParent(d);
                }
    
                dg.Focus();
                if (cell != null && dg.SelectionUnit != DataGridSelectionUnit.FullRow)
                {
                    cell.IsSelected = !row.IsSelected;
                    cell.Focus();
                }
                else
                {
                    row.IsSelected = !row.IsSelected;
                    row.Focus();
                }
            }
        }
    }



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

    • 回答としてマーク 星 睦美 2015年8月17日 1:57
    2015年8月11日 15:10

すべての返信

    • 回答としてマーク 星 睦美 2015年8月17日 1:57
    2015年8月11日 13:22
  • こんな?

    <Window x:Class="WpfApplication1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Window.Resources>
    
            <Style TargetType="{x:Type DataGridCell}">
                <EventSetter Event="PreviewMouseLeftButtonDown"
                             Handler="cell_PreviewMouseLeftButtonDown" />
    
                <EventSetter Event="PreviewTouchDown"
                             Handler="cell_PreviewTouchDown" />
            </Style>
            <Style TargetType="{x:Type DataGridRowHeader}">
                <EventSetter Event="PreviewMouseLeftButtonDown"
                             Handler="cell_PreviewMouseLeftButtonDown" />
    
                <EventSetter Event="PreviewTouchDown"
                             Handler="cell_PreviewTouchDown" />
            </Style>
        </Window.Resources>
    
        <DataGrid ItemsSource="{Binding}" DataContext="ABCDEFGHIJKLMNOPQRSTUVWXYZ" RowHeaderWidth="50" TextElement.FontSize="30" >
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding}" IsReadOnly="true" Header="Test" Width="100"/>
                <DataGridTextColumn Binding="{Binding}" IsReadOnly="true" Header="Test" Width="100"/>
            </DataGrid.Columns>
        </DataGrid>
    
    </Window>
    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Controls.Primitives;
    namespace WpfApplication1
    {
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
            bool isTouch = false;
            private void cell_PreviewTouchDown(object sender, TouchEventArgs e)
            {
                Test(sender);
                e.Handled = true;
                isTouch = true;
            }
    
            void cell_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                //TouchイベントをHandled=trueしてもMouseイベントも発生してしまうので
                //Touchイベントの後はマウスイベントの処理を阻止
                e.Handled = isTouch;
                isTouch = false;
    
                Test(sender);
            }
            private void Test(object sender)
            {
                DataGridRowHeader header = sender as DataGridRowHeader;
                DataGridCell cell = sender as DataGridCell;
                DependencyObject d = cell ?? (DependencyObject)header;
                DataGridRow row = null;
                DataGrid dg = null;
                while (d != null && row == null)
                {
                    row = d as DataGridRow;
                    d = VisualTreeHelper.GetParent(d);
                }
                while (d != null && dg == null)
                {
                    dg = d as DataGrid;
                    d = VisualTreeHelper.GetParent(d);
                }
    
                dg.Focus();
                if (cell != null && dg.SelectionUnit != DataGridSelectionUnit.FullRow)
                {
                    cell.IsSelected = !row.IsSelected;
                    cell.Focus();
                }
                else
                {
                    row.IsSelected = !row.IsSelected;
                    row.Focus();
                }
            }
        }
    }



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

    • 回答としてマーク 星 睦美 2015年8月17日 1:57
    2015年8月11日 15:10
  • 皆様

    回答頂き、ありがとうございました。

    理想としている動作が行えたのと、副産物的に別の問題も解決でき、とても満足しています。

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

    2015年8月13日 6:17