이제 WPF로 바꾸어보세요 (9)

본래의 기능인 매일의 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>

xaml 내의 listview 내의 스타일 지정은 이런 느낌
실제 표시는 이렇게.

좋은 웹페이지 즐겨찾기