ベラ ジョン カジノ 招待k8 カジノWPF:DataGridやListViewなどにデータをソートして表示するには?[XAML、C#、VB]仮想通貨カジノパチンコ上 津島 キコーナ

ベラ ジョン カジノ 招待k8 カジノWPF:DataGridやListViewなどにデータをソートして表示するには?[XAML、C#、VB]仮想通貨カジノパチンコ上 津島 キコーナ

ベラ ジョン カジノ 招待k8 カジノWPF:DataGridやListViewなどにデータをソートして表示するには?[XAML、C#、VB]仮想通貨カジノパチンコ上 津島 キコーナ

週刊 文春 最新 号 広告k8 カジノ .NET TIPSInsider.NET

パチンコ 計数 機 トラブル 

「.NET TIPS」のインデックス

連載目次

対象:.NET 4.0以降

 WPFには、データのコレクションを表示するためのコントロールが用意されている。DataGridコントロールやListViewコントロールなどがそうだ(いずれもSystem.Windows.Controls名前空間)。そこに表示するデータをソートしておくにはどうしたらよいだろうか? もちろん、与えるデータをソートしておけば可能なのだが、ソート順(昇順/降順)やソート対象の項目を変更するたびにデータを作り直すのは非効率である。CollectionViewSourceクラス(System.Windows.Data名前空間)を利用すれば、元のデータを並べ替えたり削除したりすることなく、表示だけをソート/フィルタリング/グルーピングできる。本稿では、CollectionViewSourceクラスを使って、ソートして表示する方法を解説する。

 なお、本稿のプログラミングには、無償のVisual Studio Express 2012 for Windows Desktop(以降、VS 2012)を使用した。Visual Studio 2013でも手順は同じである。

事前準備

 簡単なデータを表示/編集できるプログラムを用意する(次の画像)。画面の左側にはDataGridコントロールを、右側にはListViewコントロールを、画面下部にはデータを追加/編集するための簡単なUIを配置する。

ベースとなるプログラムを起動した画面(Windows 7)ベースとなるプログラムを起動した画面(Windows 7)この画面で、例えば[VALUE]の昇順([Blue]→[Green]→[Red])に並べ替えて表示したい。どうしたらよいだろうか?

 少々長くなるが、以下の手順に従ってコーディングしてほしい。SampleDataクラスの新設、MainWindowクラスへのUIの追加(XAML)、そしてMainWindowクラスのコードビハインドへのコードの追加(C#またはVB)を行う。

 まず、Visual StudioでWPFアプリのプロジェクトを新しく作成したら、そこに新しくクラスのファイルを追加し、その名前を「SampleData.cs/.vb」とする。ファイルの内容を次のコードのように書き換える。

using System.Collections.ObjectModel;using System.ComponentModel;namespace dotNetTips1082CS //←ここはプロジェクトによって異なる{ // 表示する個々のデータ(データバインド可能) public class SampleData : INotifyPropertyChanged { // Indexプロパティ string _index; public string Index { get { return _index; } set{_index = value; OnPropertyChanged("Index");} } // Valueプロパティ string _value; public string Value { get { return _value; } set { _value = value; OnPropertyChanged("Value"); } } // INotifyPropertyChangedインターフェースの実装 public event PropertyChangedEventHandler PropertyChanged; void OnPropertyChanged(string pName) { var handler = this.PropertyChanged; if (handler != null) handler(this, new PropertyChangedEventArgs(pName)); } } // 表示するデータのコレクション(データバインド可能) public class SampleDataCollection : ObservableCollection<SampleData> { public SampleDataCollection() { // 初期データ this.Add(new SampleData(){ Index="1", Value="Red"}); this.Add(new SampleData(){ Index="2", Value="Green"}); this.Add(new SampleData(){ Index="3", Value="Blue"}); } }}

Imports System.ComponentModelImports System.Collections.ObjectModel' 表示する個々のデータ(データバインド可能)Public Class SampleData Implements INotifyPropertyChanged ' Indexプロパティ Private _index As String Public Property Index As String Get Return _index End Get Set(value As String) _index = value : OnPropertyChanged("Index") End Set End Property ' Valueプロパティ Private _value As String Public Property Value As String Get Return _value End Get Set(value As String) _value = value : OnPropertyChanged("Value") End Set End Property ' INotifyPropertyChangedインターフェースの実装 Public Event PropertyChanged(sender As Object, e As PropertyChangedEventArgs) _ Implements INotifyPropertyChanged.PropertyChanged Private Sub OnPropertyChanged(pName As String) RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(pName)) End SubEnd Class' 表示するデータのコレクション(データバインド可能)Public Class SampleDataCollection Inherits ObservableCollection(Of SampleData) Public Sub New() ' 初期データ Me.Add(New SampleData() With {.Index = "1", .Value = "Red"}) Me.Add(New SampleData() With {.Index = "2", .Value = "Green"}) Me.Add(New SampleData() With {.Index = "3", .Value = "Blue"}) End SubEnd Class

「SampleData.cs/.vb」ファイルの内容(上:C#、下:VB)C#のコードで「namespace」に指定されている名前空間は自動生成されたもの。これは作成したプロジェクトの名前によって変化する。なお、このVBのコードでは、マルチステートメント(1行に複数のステートメントを記述する)や、Visual Basic 2008から利用できるようになったオブジェクト初期化子を使用している。

 次に、「MainWindow.xaml」ファイルを開き、ファイルの内容を次のコードのように書き換える。

<Window x:Class="dotNetTips1082CS.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" Title=".NET TIPS #1082" Height="300" Width="350" MinHeight="200" MinWidth="300" Loaded="Window_Loaded" > <d:DesignProperties.DataContext> <SampleDataCollection xmlns="clr-namespace:dotNetTips1082CS" /> <!– 上の行の名前空間の指定(=dotNetTips1082CS)はプロジェクトによって異なる。 前述のSampleDataCollectionクラスの名前空間にする –> </d:DesignProperties.DataContext> <Grid x:Name="RootGrid" Background="LightGray"> <Grid.RowDefinitions> <RowDefinition Height="*" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <!– DataGrid(画面左側):双方向バインド(UI上での変更がデータに反映される) –> <DataGrid x:Name="DataGrid1" AutoGenerateColumns="False" HorizontalAlignment="Left" ItemsSource="{Binding DataContext, Mode=TwoWay, RelativeSource={RelativeSource Self}}" SelectionChanged="DataGrid1_SelectionChanged" > <DataGrid.Columns> <DataGridTextColumn Binding="{Binding Index}" Header="INDEX" MinWidth="50" /> <DataGridTextColumn Binding="{Binding Value}" Header="VALUE" MinWidth="150" /> </DataGrid.Columns> </DataGrid> <!– ListView(画面右側):一方向バインド(UI上での変更はデータに反映されない) –> <ListView Grid.Column="1" Margin="10,0,0,0" ItemsSource="{Binding DataContext, Mode=OneWay, RelativeSource={RelativeSource Self}}" DisplayMemberPath="Value" /> <!– 画面下部のデータ編集用UI –> <StackPanel Grid.Row="1" Grid.ColumnSpan="2" Orientation="Horizontal"> <TextBlock VerticalAlignment="Center">INDEX</TextBlock> <TextBox x:Name="TextBoxIndex" Width="30" /> <TextBlock VerticalAlignment="Center" Margin="10,0,0,0">VALUE</TextBlock> <TextBox x:Name="TextBoxValue" Width="70" /> <Button Click="Button_Click" Content="Add/Renew" Margin="10,0,0,0" /> </StackPanel> </Grid></Window>

「MainWindow.xaml」ファイルにUIを記述する(XAML)冒頭の<Windows>タグの中身にも追加/変更があるので注意。特に太字にした部分を忘れないよう。また、<Windows>タグの「x:Class」属性の値は、プロジェクトごとに異なる。なお、データとコントロールを結び付けるために「データバインディング」の仕組みを利用している。詳しくは「連載:WPF入門:第5回 WPFの「データ・バインディング」を理解する」などを参照してほしい。

 最後に、「MainWindow.xaml.cs/.vb」ファイルを開き、ファイルの内容を次のコードのように書き換える。

using System.Linq;using System.Windows;using System.Windows.Controls;using System.Windows.Data;namespace dotNetTips1082CS{ public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } // 表示するデータ private SampleDataCollection _data = new SampleDataCollection(); // 画面が表示されるとき、データを画面にセットする private void Window_Loaded(object sender, RoutedEventArgs e) { // データをそのままセットする this.RootGrid.DataContext = _data; } // DataGrid1で選択行が移動したら、下端のテキストボックスにその値を反映させる private void DataGrid1_SelectionChanged(object sender, SelectionChangedEventArgs e) { var selectedData = this.DataGrid1.SelectedItem as SampleData; if (selectedData == null) { this.TextBoxIndex.Text = string.Empty; this.TextBoxValue.Text = string.Empty; } else { this.TextBoxIndex.Text = selectedData.Index; this.TextBoxValue.Text = selectedData.Value; } } // ボタンがクリックされたら、下端のテキストボックスの内容をデータに反映させる private void Button_Click(object sender, RoutedEventArgs e) { string index = this.TextBoxIndex.Text; if (string.IsNullOrWhiteSpace(index)) return; string value = this.TextBoxValue.Text; var currentData = _data.FirstOrDefault(d => d.Index == index); if (currentData == null) _data.Add(new SampleData() { Index = index, Value = value }); else currentData.Value = value; } }}

Class MainWindow ' 表示するデータ Private _data As SampleDataCollection = New SampleDataCollection() ' 画面が表示されるとき、データを画面にセットする Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs) ' データをそのままセットする Me.RootGrid.DataContext = _data End Sub ' DataGrid1で選択行が移動したら、下端のテキストボックスにその値を反映させる Private Sub DataGrid1_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Dim selectedData = TryCast(Me.DataGrid1.SelectedItem, SampleData) If (selectedData Is Nothing) Then Me.TextBoxIndex.Text = String.Empty Me.TextBoxValue.Text = String.Empty Else Me.TextBoxIndex.Text = selectedData.Index Me.TextBoxValue.Text = selectedData.Value End If End Sub ' ボタンがクリックされたら、下端のテキストボックスの内容をデータに反映させる Private Sub Button_Click(sender As Object, e As RoutedEventArgs) Dim index As String = Me.TextBoxIndex.Text If (String.IsNullOrWhiteSpace(index)) Then Return End If Dim value As String = Me.TextBoxValue.Text Dim currentData = _data.FirstOrDefault(Function(d) d.Index = index) If (currentData Is Nothing) Then _data.Add(New SampleData() With {.Index = index, .Value = value}) Else currentData.Value = value End If End SubEnd Class

「MainWindow.xaml.cs/.vb」ファイルを変更する(上:C#、下:VB)このVBのコードでは、Visual Basic 2008から利用できるようになった単一行のラムダ式やオブジェクト初期化子を使用している。

 以上で、プログラムの準備は完了だ。実行すると、冒頭の画像のようにデータが表示される([VALUE]が[Red]→[Green]→[Blue]の順になっている)。これを[VALUE]の昇順にソートして表示([Blue]→[Green]→[Red])にしたいのだ。

DataGridコントロールのソート機能

 ここでちょっと寄り道をして、DataGridコントロールに備わっているソート機能を見ておこう。

 DataGridコントロールのヘッダー部分をクリックすると、その列のデータで昇順/降順に並べ替えることができる(次の画像)。

ヘッダー部分(赤丸)をクリックヘッダー部分(赤丸)をクリック▼DataGridコントロールのソート機能(Windows 7)DataGridコントロールのソート機能(Windows 7)ヘッダー部分(赤丸)をクリックすると、その列のデータで昇順にソートされる(上)。もう一度クリックすると、降順に切り替わる(下)。なお、DataGridコントロール上で行った並べ替えは、データバインディングによって元データに反映され、それが再びデータバインディングによって右側のListViewコントロールにも反映される。

 また、ソートした状態であれば、プログラムからデータを追加したときに、正しくソートされた位置に挿入される(次の画像)。

[INDEX]テキストボックスと[VALUE]テキストボックスに値を入力して[Add/Renew]ボタンをクリック[INDEX]テキストボックスと[VALUE]テキストボックスに値を入力して[Add/Renew]ボタンをクリック▼DataGridコントロールでソートが有効のときにデータを追加する(Windows 7)DataGridコントロールでソートが有効のときにデータを追加する(Windows 7)ヘッダーで[VALUE]の昇順にソートしておき、新しいデータとして「Orange」を追加してみよう。画面下端のUIで[INDEX]テキストボックスに「4」、[VALUE]テキストボックスに「Orange」と入力して、[Add/Renew]ボタン(赤丸)をクリックすると、コードビハインドのプログラムで元データのコレクションにそれが追加される(上)。DataGridコントロールでソートが有効になっていると、正しくソートされた位置に新しいデータが挿入される(下、赤枠内)。なお、画像にはないが、DataGridコントロール上でエンドユーザーがデータを書き換えた場合も、正しくソートされた位置にデータが移動される。

 エンドユーザーが操作してソートできればよいのであれば、上記のプログラムでも十分だろう。ただし、ListViewコントロール(画面の右側)には、この機能はない。また、DataGridコントロールであっても、表示したときに(エンドユーザーの操作なしで)ソートしたいのであれば、やはりプログラムで対応する必要がある。

データをソートして表示するには?

 ソートした状態で表示するには、CollectionViewSourceクラスを使えばよい。

 正確には、CollectionViewSourceクラスを使って、元のデータコレクションから既定のビューを取り出し、それをコントロールにバインドする。そして、既定のビューに対して並べ替えを設定するのである。具体的には、次のコードのように、「MainWindow.xaml.cs/.vb」ファイルのWindow_Loadedメソッドを変更する。

// 画面が表示されるとき、データを画面にセットするprivate void Window_Loaded(object sender, RoutedEventArgs e){ // データをそのままセットする //this.RootGrid.DataContext = _data; // 上の行を削除し、以下のように書き換える // 既定のビューを取り出してセットする var view = CollectionViewSource.GetDefaultView(_data); this.RootGrid.DataContext = view; // 既定のビューにソートを指定する view.SortDescriptions.Add( new System.ComponentModel.SortDescription( "Value", System.ComponentModel.ListSortDirection.Ascending) ); // DataGridコントロールのヘッダーにソートの印(三角のマーク)を表示する this.DataGrid1.Columns[1].SortDirection = System.ComponentModel.ListSortDirection.Ascending;}

' 画面が表示されるとき、データを画面にセットするPrivate Sub Window_Loaded(sender As Object, e As RoutedEventArgs) ' データをそのままセットする 'Me.RootGrid.DataContext = _data ' 上の行を削除し、以下のように書き換える ' 既定のビューを取り出してセットする Dim view = CollectionViewSource.GetDefaultView(_data) Me.RootGrid.DataContext = view ' 既定のビューにソートを指定する view.SortDescriptions.Add( New System.ComponentModel.SortDescription( "Value", System.ComponentModel.ListSortDirection.Ascending) ) ' DataGridコントロールのヘッダーにソートの印(三角のマーク)を表示する Me.DataGrid1.Columns(1).SortDirection _ = System.ComponentModel.ListSortDirection.AscendingEnd Sub

データの既定のビューをバインドし、ソートを設定するコード(上:C#、下:VB)DataGridコントロールのヘッダーにソートの印を表示するためのSortDirectionプロパティは、.NET Framework 4で導入されたものである。それを除けば、このコードはWPFの最初のバージョンから利用できるはずだ。また、別解として、DataGridコントロールが内部的に自動生成している既定のビュー(これによって前述した手動によるソートが実現されている)を利用しても同じ結果が得られる。すなわち、view.SortDescriptionsではなく、DataGrid1.Items.SortDescriptionsにソート指定を行ってもよい(CollectionViewSourceクラスで既定のビューを取り出す必要はない)。どちらの方法を採るかは自由だが、1つのプログラムの中では統一しておいた方がよいだろう。なお、このVBのコードでは、Visual Basic 2010から利用できるようになった「暗黙の行連結」を使用している。

 このようにすれば、プログラムを起動したときからソートされた状態で表示される(次の画像)。同様にして、実行中にプログラムからソート順を切り替えることも可能である。

起動したときからソートされている(Windows 7)起動したときからソートされている(Windows 7)

利用可能バージョン:.NET Framework 4.0以降カテゴリ:WPF 処理対象:DataGridコントロール、ListViewコントロール使用ライブラリ:CollectionViewSourceクラス(System.Windows.Data名前空間)

■この記事と関連性の高い別の.NET TIPSWPF:DataGridやListViewなどのデータを変更したときに自動的に再ソートするには?[ASP.NET]GridViewコントロールのヘッダにソート方向を表示するには?[ASP.NET]DataGridコントロールのソートを双方向にするには?[ASP.NET]DataGridコントロールにソート機能を追加するには?自作クラスによる配列をソート(並べ替え)するには?(LINQ版)「.NET TIPS」のインデックス

「.NET TIPS」

仮想通貨カジノパチンコチアゴメッシ

コメントを残す

業界連盟:コニベット k8 カジノ k8 カジノ k8 カジノ パチンコ 人気 パチスロ Hithotパチスロ k8 カジノ パチンカス | Feed | RSS | sitemap.html | Sitemap