データを保存し、読み込む機能は、アプリケーションを作成するためには、必ず必要となる機能です。
そのため、プログラミングを学ぶ初期の段階で、保存と読み込みの機能を自分が作成するプログラムに組み込む方法を理解しておく必要があります。
保存と読み込みは、C#本体の機能なので、WPFとは関係ありません。WPFで作成したUIで、テキストを保存し、読み込むプログラムを作成します。
プロジェクトを作成する
「ファイル」、「新規作成」、「プロジェクト」を選択します。
インストール時に選択肢た機能に基づいて、テンプレートが用意されています。WPFアプリケーションを作成するためには、「WPFアプリ(.Net Freamework)」を選択し、場所とプロジェクトの名前を指定します。
UIを作成する
UIを作成します。MainWindow.xamlは、プログラムを実行した際に表示されるUIを定義します。
WPFのUIの作成は、デザイナーが用意されていますが、簡単なUIであれば、xamlコードを直接入力して作成したほうが楽です。
特に、コードの動作を確認するために使用する、短いプログラムのためのメインウィンドウのデザインは、いろいろ集めておくと、コードの動作検証などに便利です。
以下は、TextBoxとButtonを持つウィンドウのxamlコードです。
[xaml]
<Window x:Class="Save01.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="150" Width="300">
<DockPanel>
<Button DockPanel.Dock="Bottom" >Button03</Button>
<Button DockPanel.Dock="Bottom" >Button02</Button>
<Button DockPanel.Dock="Bottom" >Button01</Button>
<TextBox DockPanel.Dock="Top" Name="tb">TextBox</TextBox>
</DockPanel>
</Window>
クリックイベントを追加するには、デザインペインで、ボタンをダブルクリックするか、プロパティペインで、イベントを指定します。
xamlで表記したUIを流用する際は、一番上の行にあるx:Classは、自動生成された値をそのまま使用し、それ以外を貼り付けます。
C#コードから、UI内のコントロールを操作する場合は、Name属性を設定する方法が簡単です。コントロールによっては、データメンバを変更しても表示が変更されない場合があるので、その場合は、別の対応が必要です。TextBoxでは、C#でテキストプロパティを操作すると、何もしなくてもUIに反映されます。
プログラムを追加する場所
WPFプロジェクトテンプレートを使用すると、MainWindow.xamlとMainWindow.xaml.csの2つが自動で作成されます。C#コードは、MainWindow.xaml.csに記述できます。
UIにイベントを追加すると、MainWindow.xaml.csに記述されます。イベントが多くなると、コードが増えてくるので、ここに処理を行うコードを記述すると内容を把握しにくくなります。
そこで、別のcsファイルに記述し、その中のメソッドをMainWindow.xaml.csに記述されるイベントから、呼び出します。
同じプロジェクトファイルのcsファイルは、名前空間が同じであれば、参照可能です。名前空間が違う場合は、呼び出し側のusingディレクティブで、名前空間を指定します。プロジェクトをまたぐ場合は、参照として、プロジェクトを追加します。
コードが実行できる範囲であるスコープが明確でない場合は、あらかじめ、実際に簡単なコードが実行できるかどうかを確認してから、コードを作成します。
FileIOクラスを作成し、その中のtextSave01メソッドに、テキストをファイルに保存し、using文を使ってファイルを閉じるコードを作成します。
ソリューション・エクスプローラーのプロジェクト名を右クリックし、「追加」、「クラス」を選択します。
新しい項目の追加ダイアログで、クラスが選択されていることを確認し、「FileIO.cs」クラスを作成します。
保存するテキストを引数として受け取り、ファイルに、テキストファイルを保存するメソッドを持つクラスを作成します。
ファイルを安全に閉じる方法
ファイル操作は、ファイルを書き込んだあと、必ずファイルを閉じる必要があるので、そのための処理が必要です。具体的には、using文を使用する方法とCloseメソッドやDispose()メソッドを呼び出す方法やtry-finally構文を使って、CloseメソッドやDispose()メソッドを呼び出す方法があります。
今回のコードでは、using文を使用する方法とtry-finally構文を使って、Dispose()メソッドを呼び出す方法を紹介します。おすすめは、using文を使用する方法です。
using文は、C# 4.0(Visual Studio 2010)には既に存在しています。
ファイルの位置を指定する
ファイルを保存する場所は、フルパスで指定できます。パスを持たないファイル名だけを指定すると、実行ファイルと同じ位置を指定することになります。
特殊フォルダを指定する場合は、Environment.SpecialFolder 列挙型を使用します。
また、URIで指定して、パスに変換して使用する方法もあります。
完成したコード
ファイルを閉じる方法の違う2つのコードで、テキストボックスの内容をテキストファイルとして保存します。
MainWindows.xaml
<Window x:Class="Save01.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="SaveText" Height="150" Width="300">
<DockPanel>
<Button DockPanel.Dock="Bottom" Click="Button_Click_2" >読み込み</Button>
<Button DockPanel.Dock="Bottom" Click="Button_Click_1" >保存(try-finally)</Button>
<Button DockPanel.Dock="Bottom" Click="Button_Click" >保存(using)</Button>
<TextBox DockPanel.Dock="Top" Name="tb">TextBox</TextBox>
</DockPanel>
</Window>
MainWindows.xaml.cs
using System.Windows;
namespace Save01
{
/// <summary>
/// MainWindow.xaml の相互作用ロジック
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
// ボタン1のクリック・イベント
FileIO fileIo = new FileIO();
fileIo.SaveText01(tb.Text);
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
// ボタン2のクリック・イベント
FileIO fileIo = new FileIO();
fileIo.SaveText02(tb.Text);
}
private void Button_Click_2(object sender, RoutedEventArgs e)
{
// ボタン2のクリック・イベント
FileIO fileIo = new FileIO();
// ファイルの内容をテキストボックスに格納する
tb.Text = fileIo.LoadText();
}
}
}
FileIO.cs
using System;
using System.IO;
namespace Save01
{
class FileIO
{
// パスとファイル名
string filePath = @"H:\C#プロジェクト\SaveText.txt";
public void SaveText01(string TextContents)
{
// using文を使ってファイルをクローズするコード
using (StreamWriter writer = new StreamWriter(filePath))
{
// ファイルに書き込む
writer.WriteLine(TextContents);
}
}
public void SaveText02(string TextContents)
{
// try-finallyを使ってファイルをクローズするコード
StreamWriter writer = new StreamWriter(filePath);
try
{
writer.WriteLine(TextContents);
}
finally
{
writer.Dispose();
}
}
public string LoadText()
{
// ファイルの内容を読み込む
return String.Join("\r\n", File.ReadAllLines(filePath));
}
}
}
コードのダウンロード Save01.zip