2019-07-16に投稿

【WPF】右クリックメニューでデータグリッドの内容をコピーする

おはようございます。

データグリッドで、
編集まではさせないけど内容のコピーが出来ると便利なシーンってありますよね。

そんな時は、右クリックでコンテキストメニューを表示して操作させるのがいいかもしれません。
ということでやってみました。

ついでに、クリップボードの内容を貼り付ける操作と、行のコピーも実装してみます。

プログラムは下記の記事のものを流用します。
【WPF】WebBrowser に PDFファイル を表示する

画面の修正

まずは、データグリッドにコンテキストメニューを追加します。

MainWindow.xaml

            <DataGrid Name="dataGrid" HorizontalAlignment="Left" Margin="10,31,0,0" Width="497" Height="225" Style="{StaticResource grid-normal}" >
                <DataGrid.ContextMenu>
                    <ContextMenu>
                        <MenuItem x:Name="ctm_namecopy" Header="名前をコピー(_C)" Click="ctm_namecopy_Click"/>
                        <MenuItem x:Name="ctm_namepaste" Header="名前を貼り付け(_V)" Click="ctm_namepaste_Click"/>
                        <MenuItem x:Name="ctm_rowcopy" Header="行をCSVとしてコピー(_R)" Click="ctm_rowcopy_Click"/>
                    </ContextMenu>
                </DataGrid.ContextMenu>
                <DataGrid.Columns>
                    <DataGridTemplateColumn IsReadOnly="True" Header="選択" Width="50">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center" VerticalAlignment="Center" />
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                    <DataGridTextColumn Binding="{Binding No}" ClipboardContentBinding="{x:Null}" Header="No" IsReadOnly="True" Width="40" />
                    <DataGridTextColumn Binding="{Binding Name}" ClipboardContentBinding="{x:Null}" Header="名前" IsReadOnly="False" Width="80"/>
                    <DataGridTemplateColumn IsReadOnly="True" Header="性別"  CellStyle="{StaticResource dgc-combo}" Width="50">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <ComboBox Name="cmbGender" ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGrid}}, Path=DataContext.GenderList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                          DisplayMemberPath="Name" SelectedValuePath="Cd" SelectedValue="{Binding Sex}" Width="50" Background="Transparent"/>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                    <DataGridTextColumn Binding="{Binding Age}" ClipboardContentBinding="{x:Null}" Header="年齢" IsReadOnly="False" Width="40"/>
                    <DataGridTemplateColumn IsReadOnly="True" Header="種別"  CellStyle="{StaticResource dgc-combo}" Width="110">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <ComboBox Name="cmbKind" ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGrid}}, Path=DataContext.KindList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                          DisplayMemberPath="KindName" SelectedValuePath="KindCd" SelectedValue="{Binding Kind}" Width="110" Background="Transparent"/>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                    <DataGridTextColumn Binding="{Binding Favorite}" ClipboardContentBinding="{x:Null}" Header="好物" IsReadOnly="False" Width="*"/>
                </DataGrid.Columns>
            </DataGrid>

プログラムの修正

コピーメソッドの追加

次のようにメソッドを実装します。
MainWindow.xaml.cs

        /// <summary>
        /// 名前をクリップボードにコピーします.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ctm_namecopy_Click(object sender, RoutedEventArgs e)
        {
            // 選択中のデータを取得
            CatModel cat = this.dataGrid.SelectedItem as CatModel;
            if (cat != null)
            {
                try
                {
                    // クリップボードにコピー
                    Clipboard.SetText(cat.Name);
                }
                catch (Exception ex)
                {
                }
            }
        }

 

データベース上で選択された行の、名前列をクリップボードにコピーします。
簡単なものですね。

貼り付けメソッドの追加

次のようにメソッドを実装します。
MainWindow.xaml.cs

        /// <summary>
        /// クリップボードの名前を貼り付け
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ctm_namepaste_Click(object sender, RoutedEventArgs e)
        {
            // 選択中のデータを取得
            CatModel cat = this.dataGrid.SelectedItem as CatModel;
            if (cat != null)
            {
                String name = Clipboard.GetText();
                cat.Name = name;
                this.dataGrid.Items.Refresh();
            }
        }

 

選択された行の名前列の内容をクリップボードの内容で上書きします。
リフレッシュメソッドを呼び出すことで内容が即座に反映されます。

行コピーメソッドの追加

次のようにメソッドを実装します。
MainWindow.xaml.cs

        /// <summary>
        /// 行をカンマ区切り文字列にしてクリップボードにコピーします.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ctm_rowcopy_Click(object sender, RoutedEventArgs e)
        {
            // 選択中のデータを取得
            CatModel cat = this.dataGrid.SelectedItem as CatModel;
            if (cat != null)
            {
                // データをCSV形式に変換
                String delmiter = ",";
                StringBuilder sb = new StringBuilder();
                sb.Append(cat.No).Append(delmiter);
                sb.Append(cat.Name).Append(delmiter);
                sb.Append(cat.Sex).Append(delmiter);
                sb.Append(cat.Age).Append(delmiter);

                KindConverter kindConverter = new KindConverter();
                sb.Append(kindConverter.Convert(cat.Kind, null,null,null)).Append(delmiter);

                sb.Append(cat.Favorite);
                try
                {
                    // クリップボードにコピー
                    Clipboard.SetText(sb.ToString());
                }
                catch (Exception ex)
                {
                }
            }
        }

 

こちらはコピーの応用で、選択された行の内容をカンマ区切りに編集し
クリップボードにコピーします。

まとめ

思っていたより簡単に実装できました。
クライアントソフトならではの手軽さですかね。
(WEBはセキュリティとかの問題でコピーとかが意外に面倒)

コンテキストメニュー自体は階層も持たすことができますし、
色々なことに利用できそうですね。
何か思いついたらやってみようと思います。

ではでは。

Originally published at www.doraxdora.com
ツイッターでシェア
みんなに共有、忘れないようにメモ

doraxdora

IT関係の仕事をしています/1985年生まれの東京在住/便利なサービスやツール漁りや料理などが好き/2017年~ブログやってます/自分でサービスとか作ってリリースしたい/何かありましたらお気軽にDMどうぞ

Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

有料記事を販売できるようになりました!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?

コメント