本来の機能である毎日のPC起動時間と終了時間をテキストに保存して、リスト表示する部分のロジックをVB→C#に置き換え。
ListviewへのCSVファイル内容のセット
読み込んだテキストバッファをCRLF区切りでSPLITして行配列化、さらに各行をカンマでSPLITして出来上がったフィールド配列をアイテムに突っ込むというベタな手順。
VB+Formsの時はこんな感じ
Dim i As Integer
For i = 0 To UBound(lines) - 1
Dim cols() = Split(lines(i), ",")
Dim itemx As New ListViewItem
Dim e_w() = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"}
'アイテムの作成
itemx.Text = Mid(cols(0), 5, 2) & "/" & Mid(cols(0), 7, 2) '日付
'アイテムの追加
itemx.SubItems.Add(e_w(Int(cols(1)))) '曜日
If Int(cols(1)) = 0 Then
itemx.UseItemStyleForSubItems = False
itemx.SubItems(1).ForeColor = Color.Red
End If
If Int(cols(1)) = 6 Then
itemx.UseItemStyleForSubItems = False
itemx.SubItems(1).ForeColor = Color.Blue
End If
itemx.SubItems.Add(cols(2)) '開始時間
itemx.SubItems.Add(cols(3)) '終了時間
Me.ListView1.Items.Add(itemx)
Next i
おんなじListviewだし、Formsと大して変わらんだろうと思ってましたが考えが甘かった。結構迷う。
なによりWPFのListviewはサブアイテムなどというものがない模様。
でさらにItem内容を書き換えてもRefreshしてやらないと画面更新されない。
リスト作成はWPF+C#の場合、
private void MakeListView(string Buff)
{
//ListViewを作成
//曜日
string[] e_w = { "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};
//行配列化、さらにフィールド分解してListViewItemとして追加
string[] crlf = { "\r\n" };
string[] lines = Buff.Split(crlf, StringSplitOptions.None);
string[] dlm = { "," };
for (int i = 0; i < lines.Length-1; i++)
{
string[] fld = lines[i].Split(dlm, StringSplitOptions.None);
fld[0] = fld[0].Substring(4, 2) + "/" + fld[0].Substring(6,2);
fld[1] = e_w[int.Parse(fld[1])];
this.listView.Items.Add(fld);
}
this.listView.Items.Refresh();
}
さらにリスト内のアイテムを動的に更新する場合ベタなループで、
//Listview上で特定条件の行の特定項目を更新する
for(int i=0;i<listView.Items.Count;i++)
{
string[] fld = (string[])listView.Items[i]; //1行分を配列に入れる
if (fld[0] == "AAA")
{
fld[0]="xxx"
listView.Items[i] = fld; //こんな感じで配列をそのまま突っ込む
}
}
listView.Items.Refresh();
てな感じで対応。foreachを使ったほうが早い模様ですが、どのみち更新するためのインデックスがいるので、わかりやすさからforで処理記述しています。
追記
当初上のようにstringの配列を直接listviewのアイテムに入れてましたが、最終的にはリスト1行のデータ(日付、曜日、起動時刻、終了時刻)をclassにして代入してます。
単にlistviewに入れるだけなら問題ないのですが、土曜日を青文字、日曜を赤文字にするためにはxaml側でtrigger設定してstyle適用しないと無理なようで、そのため仕方なく・・。
ここまで極力xamlを触らないやり方で進めてきたんですがこれはいかんともしがたい模様。formsの場合はitem内でスタイル指定できてたんで、どうとでもなったんですが。
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="BorderBrush" Value="LightGray"/>
<Setter Property="BorderThickness" Value="0,0,0,0.5"/>
<Style.Triggers>
<DataTrigger Binding="{Binding dow}" Value="SUN">
<Setter Property="Foreground" Value="Red"/>
</DataTrigger>
<DataTrigger Binding="{Binding dow}" Value="SAT">
<Setter Property="Foreground" Value="Blue" />
</DataTrigger>
<Trigger Property="IsSelected" Value="True" >
<Setter Property="Background" Value="{x:Static SystemColors.HighlightBrush}" />
<Setter Property="Foreground" Value="{x:Static SystemColors.HighlightTextBrush}" />
</Trigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>