Home > C# > WPF > WPFコントロール > ListView

C# WPF ListViewのデーターソースを保存する

新規作成日 2019-01-18
最終更新日

ListViewのデータソースとして使用しているリスト型のデータをTSV(タグ区切りの値)としてファイルに保存します。

再利用性の高い機能は、コードを独立させて再利用性を高めたいのですが、データスコープの問題があるので、実際に考えるとどのように分割するのか、プログラム全体を見直す必要があります。

しかし、今回は、再利用性は、考えず、最低限動作するコードを考えてみることにします。

これまでのコードに、リストを保存、そして、読み込むUIとコードを追加します。

ListViewのデータソースとして使用していても、実態は、複数のデータ・メンバを持つクラスのリスト型(ここでは、ObservableCollectionクラス)配列です。行うことは、単純に、それぞれのデータメンバを取り出して、ファイルに書き込むだけです。

UIに「リスト保存」ボタンを設置し、クリックイベントを追加します。クリックイベントに、ListViewのデータソースとして利用しているObservableCollection型のクラスの内容をTSV形式で、ファイルに保存するコードを記述します。

List型のデータの中身を取り出すには、foreachループを使います。

ObservableCollection型のリストは、以下のように定義しています。

ObservableCollection<SerchReplacePair> SerchReplacePairs = new ObservableCollection<SerchReplacePair>();

public void SetInitialList()
{
    SerchReplacePairs.Add
        (new SerchReplacePair()
        {
            SerchString = "検索",
            ReplaceString = "置換"
        });
    SerchReplacePairs.Add
        (new SerchReplacePair()
        {
            SerchString = "犬",
            ReplaceString = "猫"
        });
    // ListViewのItemSourceに指定する
    ReplaceList.ItemsSource = SerchReplacePairs;
}

foreachループで取り出して、ファイルに保存します。

private void ListSaveButton_Click(object sender, RoutedEventArgs e)
{
    // 置換リストを保存する
    // 保存対象のリスト SerchReplacePairs

    // パスとファイル名
    string filePath = @"H:\C#プロジェクト\ReplacePair.tsv";


    // using文を使ってファイルをクローズするコード

    using (StreamWriter writer = new StreamWriter(filePath))
    {
        foreach(SerchReplacePair n in SerchReplacePairs)
        {
            // ファイルに書き込む
            writer.WriteLine(n.SerchString + "\t" +n.ReplaceString);
        }
    }
}

複数のデータ・メンバを持つクラスのリスト型(ここでは、ObservableCollectionクラス)配列から、それぞれの値を取り出す操作は、一度理解してしまえば簡単なのですが、基本的すぎて、項目としては、ほとんどコード例として取り上げられていません。その上、キーワード検索で見つけるのも困難です。そのため、最初に使うときに、探し回るのは仕方ないと考え、覚えてしまいましょう。また、"\t"は、タブを表します。

ファイルの保存先をUIで指定できるようにする

先程のコードは、保存先が固定です。

UIから、保存先を選択できるように変更します。

パスとファイル名を格納する変数をテキストボックに格納し、使用する際は、そのテキストボックスの値を使用します。

public MainWindow()
{
    InitializeComponent();
    SetInitialList();
    // パスとファイル名を設定
    ReplacListBox.Text = @"H:\C#プロジェクト\ReplacePair.tsv";
}


private void ListSaveButton_Click(object sender, RoutedEventArgs e)
{
    // 置換リストを保存する
    // 保存対象のリスト SerchReplacePairs

    // using文を使ってファイルをクローズするコード
  // ファイル名は、テキストボックスから取得する

    using (StreamWriter writer = new StreamWriter(ReplacListBox.Text))
    {
        foreach(SerchReplacePair n in SerchReplacePairs)
        {
            // ファイルに書き込む
            writer.WriteLine(n.SerchString + "\t" +n.ReplaceString);
        }
    }
}

TSVファイルからリスト・データを読み込む

Tsvファイルにデータを保存したら、Tsvファイルからデータを読み込む事ができるようにしておく必要があります。

Tsvファイルを直接テキストエディタなどで修正した際、区切り文字の入力を間違うと、必要な数の項目が取得できません。 SerchReplacePairsに、nullを登録しようとするとエラーが発生するので、取得した項目の数を確認し、2つ以下であれば、登録を行いません。

private void SelectButton_Click(object sender, RoutedEventArgs e)
{
    //Tsvファイルから、リストデータを読み込む
    using (StreamReader reader = new StreamReader(ReplacListBox.Text, Encoding.UTF8))
    {
        SerchReplacePairs.Clear();

        while (!reader.EndOfStream)     // ファイルの終末まで読み込む
        {
            string Line = reader.ReadLine();    // 1行ずつ読み込む

            string[] items = Line.Split('\t');  // テキストを区切り文字で分割する

            if (items.Length >= 2)  // 要素数が2より小さい場合は、リストに登録しない
            {
                SerchReplacePairs.Add
                    (new SerchReplacePair()
                    {
                        SerchString = items[0],
                        ReplaceString = items[1]
                    });
            }
        }
    }
}

UIデザイン

リストをファイルに保存するボタンと読み込むボタンを追加した。

SerchReplacePair.cs

namespace SerchAndReplace03
{
    class SerchReplacePair
    {
        public string SerchString { get; set; }
        public string ReplaceString { get; set; }
    }
}

MainWindow.xaml

<Window x:Class="SerchAndReplace03.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        Title="MainWindow" Height="300" Width="400">
    <DockPanel>

        <DockPanel DockPanel.Dock="Top">
            <Button Name="ListSaveButton" 
                    Margin="0,5,5,0" Height="23" Width="60" DockPanel.Dock="Right" Click="ListSaveButton_Click">リスト保存</Button>
            <Button Name="SelectButton" 
                    Margin="5,5,5,0" Height="23" Width="60" DockPanel.Dock="Right" Click="SelectButton_Click">リスト読込</Button>
            <TextBox Name="ReplacListBox" 
                     Margin="5,5,0,0" Height="23" />
        </DockPanel>
        <DockPanel DockPanel.Dock="top">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"></ColumnDefinition>
                    <ColumnDefinition Width="*"></ColumnDefinition>
                </Grid.ColumnDefinitions>
                <TextBox Name="Add_SerchString" 
                         Margin="5,5,0,0" Height="23" Grid.Column="0"/>
                <TextBox Name="Add_ReplaceString" 
                         Margin="5,5,5,0" Height="23" Grid.Column="1"/>
            </Grid>
        </DockPanel>
        <DockPanel DockPanel.Dock="top">
            <StackPanel Orientation="Horizontal" 
                        HorizontalAlignment="Right" 
                        Margin="0,0,5,0">

                <Button Name="AddButton" 
                        Margin="5,5,0,0" Height="23" Width="50" Click="AddButton_Click" 
                        >追加</Button>
                <Button Name="EditButton" 
                        Margin="5,5,0,0" Height="23" Width="50" Click="EditButton_Click" 
                        >修正</Button>
                <Button Name="DeleteButton" 
                        Margin="5,5,0,0" Height="23" Width="50" Click="DeleteButton_Click" 
                        >削除</Button>

            </StackPanel>
        </DockPanel>
        <DockPanel DockPanel.Dock="Top">
            <StackPanel Orientation="Horizontal" 
                    HorizontalAlignment="Center" Margin="0,5,0,0">

                <ListView Name="ReplaceList" 
                      SelectionChanged="ReplaceList_SelectionChanged">
                    <ListView.View>
                        <GridView>
                            <GridViewColumn Header="検索文字列" 
                                        DisplayMemberBinding="{Binding SerchString}" />
                            <GridViewColumn Header="置換文字列" 
                                        DisplayMemberBinding="{Binding ReplaceString}" />
                        </GridView>
                    </ListView.View>
                </ListView>

                <StackPanel VerticalAlignment="Center"  Margin="5,0,0,0">
                    <Button Name="upRow" Click="UpRow_Click">△</Button>
                    <Button Name="downRow" Margin="0,5,0,0" Click="DownRow_Click">▽</Button>
                </StackPanel>

            </StackPanel>
        </DockPanel>

    </DockPanel>
</Window>

MainWindow.xaml.cs

using System.Collections.ObjectModel;
using System.IO;
using System.Text;
using System.Windows;
using System.Windows.Controls;

namespace SerchAndReplace03
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            SetInitialList();
            // パスとファイル名を設定
            ReplacListBox.Text = @"H:\C#プロジェクト\ReplacePair.tsv";
        }

        ObservableCollection<SerchReplacePair> SerchReplacePairs = new ObservableCollection<SerchReplacePair>();

        public void SetInitialList()
        {
            SerchReplacePairs.Add
                (new SerchReplacePair()
                {
                    SerchString = "検索",
                    ReplaceString = "置換"
                });
            SerchReplacePairs.Add
                (new SerchReplacePair()
                {
                    SerchString = "犬",
                    ReplaceString = "猫"
                });
            // ListViewのItemSourceに指定する
            ReplaceList.ItemsSource = SerchReplacePairs;
        }

        private void ReplaceList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            // 項目を選択したとき、それぞれのメンバを表示する

            // ListViewで何も選択されていない場合は何もしない
            if (ReplaceList.SelectedItem == null) return;

            // ListViewで選択されている項目を取り出す
            SerchReplacePair ListItem = (SerchReplacePair)ReplaceList.SelectedItem;

            //  ListViewで選択されている項目をテキストボックスに表示する
            Add_SerchString.Text = ListItem.SerchString;
            Add_ReplaceString.Text = ListItem.ReplaceString;
        }

        private void AddButton_Click(object sender, RoutedEventArgs e)
        {
            // Listの項目を追加

            SerchReplacePairs.Add
                (new SerchReplacePair()
                {
                    SerchString = Add_SerchString.Text,
                    ReplaceString = Add_ReplaceString.Text
                });
        }

        private void DeleteButton_Click(object sender, RoutedEventArgs e)
        {
            // 選択した項目を削除

            // listに項目が無い場合は何もしない
            if (SerchReplacePairs.Count < 1) return;

            // ListViewで選択されている項目を取り出す
            SerchReplacePair item = (SerchReplacePair)ReplaceList.SelectedItem;

            // listから選択された項目と一致するものを削除する
            SerchReplacePairs.Remove(item);

            // テキストボックスの内容をクリア

            Add_SerchString.Text = null;
            Add_ReplaceString.Text = null;
        }

        private void EditButton_Click(object sender, RoutedEventArgs e)
        {
            // 選択した項目を修正(選択した項目を変更する)

            // ListViewで何も選択されていない場合は何もしない
            if (ReplaceList.SelectedItem == null) return;

            //選択されたアイテムのインディックスを取得する(挿入位置)
            int itemIndex = ReplaceList.SelectedIndex;

            // ListViewで選択されている項目を取り出す
            SerchReplacePair item = (SerchReplacePair)ReplaceList.SelectedItem;

            // listから選択された項目と一致するものを削除する
            SerchReplacePairs.Remove(item);

            //  SerchReplacePairsに項目を挿入する
            SerchReplacePairs.Insert
                (itemIndex, new SerchReplacePair()
                {
                    SerchString = Add_SerchString.Text,
                    ReplaceString = Add_ReplaceString.Text
                });
        }

        private void UpRow_Click(object sender, RoutedEventArgs e)
        {
            // リストの項目を上に移動する

            // ListViewで何も選択されていない場合は何もしない
            if (ReplaceList.SelectedItem == null) return;

            //選択されたアイテムのインディックスを取得する(挿入位置)
            int itemIndex = ReplaceList.SelectedIndex;

            // 項目が先頭の場合は何もしない
            if (itemIndex == 0) return;

            // ListViewで選択されている項目を取り出す
            SerchReplacePair item = (SerchReplacePair)ReplaceList.SelectedItem;

            // listから選択された項目と一致するものを削除する
            SerchReplacePairs.Remove(item);

            //  SerchReplacePairsに項目を挿入する
            SerchReplacePairs.Insert(itemIndex - 1, item);
        }

        private void DownRow_Click(object sender, RoutedEventArgs e)
        {
            // リストの項目を下に移動する

            // ListViewで何も選択されていない場合は何もしない
            if (ReplaceList.SelectedItem == null) return;

            //選択されたアイテムのインディックスを取得する(挿入位置)
            int itemIndex = ReplaceList.SelectedIndex;

            // 項目が末尾の場合は何もしない
            if (itemIndex == ReplaceList.Items.Count - 1) return;

            // ListViewで選択されている項目を取り出す
            SerchReplacePair item = (SerchReplacePair)ReplaceList.SelectedItem;

            // listから選択された項目と一致するものを削除する
            SerchReplacePairs.Remove(item);

            //  SerchReplacePairsに項目を挿入する
            SerchReplacePairs.Insert(itemIndex + 1, item);
        }

        private void ListSaveButton_Click(object sender, RoutedEventArgs e)
        {
            // 置換リストを保存する
            // 保存対象のリスト SerchReplacePairs

            // using文を使ってファイルをクローズするコード
            // ファイル名は、テキストボックスから取得する

            using (StreamWriter writer = new StreamWriter(ReplacListBox.Text))
            {
                foreach (SerchReplacePair n in SerchReplacePairs)
                {
                    // ファイルに書き込む
                    writer.WriteLine(n.SerchString + "\t" + n.ReplaceString);
                }
            }
        }

        private void SelectButton_Click(object sender, RoutedEventArgs e)
        {
            //Tsvファイルから、リストデータを読み込む
            using (StreamReader reader = new StreamReader(ReplacListBox.Text, Encoding.UTF8))
            {
                SerchReplacePairs.Clear();

                while (!reader.EndOfStream)     // ファイルの終末まで読み込む
                {
                    string Line = reader.ReadLine();    // 1行ずつ読み込む

                    string[] items = Line.Split('\t');  // テキストを区切り文字で分割する

                    if (items.Length >= 2)  // 要素数が2より小さい場合は、リストに登録しない
                    {
                        SerchReplacePairs.Add
                            (new SerchReplacePair()
                            {
                                SerchString = items[0],
                                ReplaceString = items[1]
                            });
                    }
                }
            }
        }
    }
}
このエントリーをはてなブックマークに追加

Home PC C# Illustration

Copyright (C) 2011 Horio Kazuhiko(kukekko) All Rights Reserved.
kukekko@gmail.com
ご連絡の際は、お問い合わせページのURLの明記をお願いします。
「掲載内容は私自身の見解であり、所属する組織を代表するものではありません。」