WPFでリストビューの情報をエクセルに貼り付けられる状態でコピーする

提供: とある社畜の頭脳整理
移動先: 案内検索

わかっている人だったら、当たり前になってしまっていると思うのだけど…なんとなく覚書で書き留めておくんだよ。エクセルで表をコピーしてテキストエディタに貼り付けると、タブ区切りのCSVになっていると思うんだ。つまり、エクセルに貼り付けられるようにするためには、リストビューの情報をタブ区切りのテキストでクリップボードにコピーすればいいってことなんだよ。

モデル

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;

namespace ClipBordCopySample
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        /// <summary>
        /// ViewModel
        /// </summary>
        private MainWindowDataContext m_MainWindowDataContext;

        /// <summary>
        /// 標準のコンストラクタ
        /// </summary>
        public MainWindow()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 画面表示イベントハンドラ
        /// </summary>
        /// <param name="sender">イベント送信元オブジェクト</param>
        /// <param name="e">イベント情報</param>
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            this.m_MainWindowDataContext = new MainWindowDataContext();
            this.DataContext = this.m_MainWindowDataContext;
            this.m_MainWindowDataContext.ListViewItems.Add(new ListViewItem() { Name = "愛 植尾", Sex = "男性", Age = 20 });
            this.m_MainWindowDataContext.ListViewItems.Add(new ListViewItem() { Name = "夏季 久家子", Sex = "女性", Age = 25 });
        }

        /// <summary>
        /// コンテキストメニュークリックイベントハンドラ
        /// </summary>
        /// <param name="sender">イベント送信元オブジェクト</param>
        /// <param name="e">イベント情報</param>
        private void MenuItem_Click(object sender, RoutedEventArgs e)
        {
            this.ClipBordCopy();
        }

        /// <summary>
        /// リストビューキーボード押下イベントハンドラ
        /// </summary>
        /// <param name="sender">イベント送信元オブジェクト</param>
        /// <param name="e">イベント情報</param>
        private void ListView_KeyDown(object sender, KeyEventArgs e)
        {
            if (Keyboard.Modifiers == ModifierKeys.Control && e.Key == Key.C)
            {
                this.ClipBordCopy();
            }
        }

        /// <summary>
        /// クリップボードコピー処理
        /// </summary>
        private void ClipBordCopy()
        {
            //クリップボードに設定する文字列宣言とヘッダー設定
            String l_CopyString = "名前\t性別\t年齢\r\n";

            //リストで選択されている行の情報を文字列に連結
            foreach(ListViewItem f_ListViewItem in this.ListView.SelectedItems)
            {
                l_CopyString +=
                    f_ListViewItem.Name + "\t" +
                    f_ListViewItem.Sex + "\t" +
                    f_ListViewItem.Age + "\r\n";
            }

            //クリップボードにコピー
            Clipboard.SetText(l_CopyString);
        }
    }
}

ビュー

<Window x:Class="ClipBordCopySample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow"
        Height="600"
        Width="800"
        Loaded="Window_Loaded">
    <Grid>
        <ListView
            x:Name="ListView"
            ItemsSource="{Binding ListViewItems}"
            KeyDown="ListView_KeyDown">
            <ListView.ContextMenu>
                <ContextMenu>
                    <MenuItem
                        Header="コピー"
                        Click="MenuItem_Click"/>
                </ContextMenu>
            </ListView.ContextMenu>
            <ListView.View>
                <GridView>
                    <GridViewColumn
                        Header="名前"
                        DisplayMemberBinding="{Binding Name}"/>
                    <GridViewColumn
                        Header="性別"
                        DisplayMemberBinding="{Binding Sex}"/>
                    <GridViewColumn
                        Header="年齢"
                        DisplayMemberBinding="{Binding Age}"/>
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>
</Window>

ビューモデル

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

//追加
using System.Collections.ObjectModel;

namespace ClipBordCopySample
{
    /// <summary>
    /// ViewModel
    /// </summary>
    class MainWindowDataContext
    {
        /// <summary>
        /// リストビューに表示するデータコンテナ
        /// </summary>
        public ObservableCollection<ListViewItem> ListViewItems { set; get; }

        /// <summary>
        /// 標準のコンストラクタ
        /// </summary>
        public MainWindowDataContext()
        {
            this.ListViewItems = new ObservableCollection<ListViewItem>();
        }
    }

    /// <summary>
    /// リストビューのアイテム
    /// </summary>
    class ListViewItem
    {
        /// <summary>
        /// 名前
        /// </summary>
        public String Name { set; get; }

        /// <summary>
        /// 性別
        /// </summary>
        public String Sex { set; get; }

        /// <summary>
        /// 年齢
        /// </summary>
        public Int32 Age { set; get; }
    }
}