2013年5月14日火曜日

DataGridで表示してみる

昨日と同じ内容を、DataGridで表示してみます
        <DataGrid ItemsSource="{Binding People}" />
とするとbindingしている内容が表示される模様

変わっているのは、表題部分をクリックするとデータをソートしてくれるところが便利かと思いましたが、他は何が違うのかは調べてみたいと思います

ListViewのようにHeaderは明示的に設定してませんが、メンバ名が表示される模様
ViewModel側は特に変えていないのでView側から見ていきます

--- View
<Window x:Class="DataGrid_130512.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:l="clr-namespace:DataGrid_130512"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <l:MainWindowViewModel />
    </Window.DataContext>
    <Grid>
        <!-- 基本的にここを変えただけ -->
        <DataGrid ItemsSource="{Binding People}" />
    </Grid>
</Window>

--- ViewModel
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Practices.Prism.ViewModel;
using System.Collections.ObjectModel;
using System.Windows;

namespace DataGrid_130512
{
    class MainWindowViewModel : NotificationObject
    {
        ObservableCollection<Person> _people = new ObservableCollection<Person>();
        public ObservableCollection<Person> People
        {
            get { return _people; }
            set { _people = value; }
        }

        /// <summary>
        /// コンストラクタ
        /// </summary>
        public MainWindowViewModel()
        {
            // 表示データの生成
            _people.Add(new Person("Stan Hansen", 6));
            _people.Add(new Person("Bruiser Brody", 5));
            _people.Add(new Person("Terry Funck", 10));
        }

        /// <summary>
        /// 選択されている人
        /// </summary>
        public Person SelectedPerson { get; set; }

        public void Execute()
        {
            if (SelectedPerson != null)
            {
                MessageBox.Show(SelectedPerson.Name);
            }
            else
            {
                MessageBox.Show("選択されていません");
            }
        }
    }

    // ListBoxに表示するデータ
    public class Person
    {
        public string Name { get; set; }
        public int TitleCount { get; set; }

        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="name"></param>
        /// <param name="count"></param>
        public Person(string name, int count)
        {
            Name = name;
            TitleCount = count;
        }
    }
}


2013年5月13日月曜日

ListViewで1行毎にシマシマ表示にしてみる

ListViewでAlternationPropertyを設定するとシマシマ表示が出来るらしいので試してみます

ListViewのItemContainerStyleを設定するようです

--- View側
<Window x:Class="ListViewTest_130508.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:l="clr-namespace:ListViewTest_130508"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <l:MainWindowViewModel />
    </Window.DataContext>
    <Grid>
        <ListView x:Name="listView1"
                 ItemsSource="{Binding People}"
                 SelectedItem="{Binding SelectedPerson}"
                 SelectionMode="Multiple"
                 AlternationCount="2" >
            <ListView.View>
                <GridView>
                    <GridView.Columns>
                        <GridViewColumn Header="Name"
                                        Width="150"
                                        DisplayMemberBinding="{Binding Name}" />
                        <GridViewColumn Header="Title Count"
                                        Width="100"
                                        DisplayMemberBinding="{Binding TitleCount}" />
                    </GridView.Columns>
                </GridView>
            </ListView.View>
            <!-- AlternationCountプロパティを使ってみる -->
            <ListView.ItemContainerStyle>
                <Style TargetType="ListViewItem">
                    <Style.Triggers>
                        <Trigger Property="ItemsControl.AlternationIndex" Value="0">
                            <Setter Property="Background" Value="Aqua" />
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </ListView.ItemContainerStyle>
        </ListView>
    </Grid>
</Window>

--- ViewModel側 (こちらは特に変更はなしです)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Practices.Prism.ViewModel;

using System.Collections.ObjectModel;
using System.Windows;

namespace ListViewTest_130508
{
    public class MainWindowViewModel : NotificationObject
    {
        ObservableCollection<Person> _people = new ObservableCollection<Person>();
        public ObservableCollection<Person> People
        {
            get { return _people; }
            set { _people = value; }
        }

        /// <summary>
        /// コンストラクタ
        /// </summary>
        public MainWindowViewModel()
        {
            // 表示データの生成
            _people.Add(new Person("Stan Hansen", 3));
            _people.Add(new Person("Bruiser Brody", 5));
            _people.Add(new Person("Terry Funck", 10));
        }

        /// <summary>
        /// 選択されている人
        /// </summary>
        public Person SelectedPerson { get; set; }

        public void Execute()
        {
            if (SelectedPerson != null)
            {
                MessageBox.Show(SelectedPerson.Name);
            }
            else
            {
                MessageBox.Show("選択されていてません");
            }
        }
    }

    // ListBoxに表示するデータ
    public class Person
    {
        public string Name { get; set; }
        public int TitleCount { get; set; }

        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="name"></param>
        /// <param name="count"></param>
        public Person(string name, int count)
        {
            Name = name;
            TitleCount = count;
        }
    }
}


2013年5月12日日曜日

ListViewを使ってみる

前回は(なんとなく)ListBoxを使ってItemsControlの表示をしてみましたが、複数"列"のデータを表示する場合はListViewを使うようです

MSDNでもどちらをチョイスするかの基準が記載されています
http://msdn.microsoft.com/ja-jp/library/aa511485.aspx

以下抜粋します
リスト ボックスリスト ビュー
データ型データとプログラム オプションの両方。データのみ。
コンテンツラベルのみ。ラベルおよび補助データ。複数列の場合もあります。
対話操作選択に使用。選択に使用。ただし、多くの場合はデータの表示と対話操作のために使用されます。ドラッグ ソースまたはドロップ ターゲットとなることができます。
提示方法固定。ビューの変更、グループ化、列ごとの並べ替え、列の幅と順序の変更が可能です。
  • 一覧に表示されるものが、プログラム オプションではないデータかどうか。該当しない場合は、代わりにリスト ボックスを使用することを検討します。
  • ビューの変更、グループ化、列ごとの並べ替え、列の幅と順序の変更が必要かどうか。該当しない場合は、代わりにリスト ボックスを使用します。
  • コントロールが、ドラッグ ソースまたはドロップ ターゲットとして機能する必要があるかどうか。該当する場合は、リスト ビューを使用します。
  • リスト アイテムをクリップボード経由でコピーする必要があるかどうか。該当する場合は、リスト ビューを使用します。
 ---
ちょっと使ってみます

--- ViewModel側(ListBoxのコードにもうひと項目追加)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Practices.Prism.ViewModel;

using System.Collections.ObjectModel;
using System.Windows;

namespace ListViewTest_130508
{
    public class MainWindowViewModel : NotificationObject
    {
        ObservableCollection<Person> _people = new ObservableCollection<Person>();
        public ObservableCollection<Person> People
        {
            get { return _people; }
            set { _people = value; }
        }

        /// <summary>
        /// コンストラクタ
        /// </summary>
        public MainWindowViewModel()
        {
            // 表示データの生成
            _people.Add(new Person("Stan Hansen", 3));
            _people.Add(new Person("Bruiser Brody", 5));
            _people.Add(new Person("Terry Funck", 10));
        }

        /// <summary>
        /// 選択されている人
        /// </summary>
        public Person SelectedPerson { get; set; }

        public void Execute()
        {
            if (SelectedPerson != null)
            {
                MessageBox.Show(SelectedPerson.Name);
            }
            else
            {
                MessageBox.Show("選択されていてません");
            }
        }
    }

    // ListBoxに表示するデータ
    public class Person
    {
        public string Name { get; set; }
        public int TitleCount { get; set; }

        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="name"></param>
        /// <param name="count"></param>
        public Person(string name, int count)
        {
            Name = name;
            TitleCount = count;
        }
    }
}

--- View側
"<GridViewColumn>"の部分がミソでしょうか

<Window x:Class="ListViewTest_130508.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:l="clr-namespace:ListViewTest_130508"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <l:MainWindowViewModel />
    </Window.DataContext>
    <Grid>
        <ListView x:Name="listView1"
                 ItemsSource="{Binding People}"
                 SelectedItem="{Binding SelectedPerson}"
                 SelectionMode="Multiple" >
            <ListView.View>
                <GridView>
                    <GridView.Columns>
                        <GridViewColumn Header="Name"
                                        Width="150"
                                        DisplayMemberBinding="{Binding Name}" />
                        <GridViewColumn Header="Title Count"
                                        Width="100"
                                        DisplayMemberBinding="{Binding TitleCount}" />
                    </GridView.Columns>
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>
</Window>



2013年5月6日月曜日

ItemsControlとObservableCollectionによる表示

ListViewなど複数のデータを表示する場合、DataSourceとしてObservableCollectionを使うとデータに変化があった場合にView側に通知されるので便利なようです。

まずは簡単な使い方から試していこうかと思います

以下の例は
- ViewModel側でObservableCollectionであるPeopleを初期化
- View側は↑をItemsSourceとしてDataBindし、ListBox.ItemTemplateで単一データを表示
- 選択状態は SelctedItemでDataBind
という感じの動作(というか表示)としています

今回はDataContextをコードビハインドで行わずにxamlで書いています
(これでもOKのようなので)

--- MainWindowViewModel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Practices.Prism.ViewModel;

using System.Collections.ObjectModel;
using System.Windows;


namespace ListViewTest_130430
{
    public class MainWindowViewModel
    {
        ObservableCollection<Person> _people = new ObservableCollection<Person>();
        public ObservableCollection<Person> People {
                    get { return _people; }
                    set { _people = value; }
        }

        /// <summary>
        /// コンストラクタ
        /// </summary>
        public MainWindowViewModel()
        {
            // 表示データの生成
            ObservableCollection<Person> people = new ObservableCollection<Person>();
            string[] names = new string[]{ "Stan Hansen", "Bruiser Brody", "Terry Funck", "Dick Murdoch"};
            foreach (string name in names)
            {
                Person p = new Person();
                p.Name = name;
                _people.Add(p);
            }
        }

        /// <summary>
        /// 選択されている人
        /// </summary>
        public Person SelectedPerson { get; set; }

        public void Execute()
        {
            if (SelectedPerson != null)
            {
                MessageBox.Show(SelectedPerson.Name);
            }
            else
            {
                MessageBox.Show("選択されていてません");
            }
        }
    }

    // ListBoxに表示するデータ
    public class Person
    {
        public string Name { get; set; }
    }
}


--- MainWindow.xaml
<Window x:Class="ListViewTest_130430.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:l="clr-namespace:ListViewTest_130430"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <l:MainWindowViewModel />
    </Window.DataContext>
    <Grid>
        <ListBox x:Name="listBox1"
                 ItemsSource="{Binding People}"
                 SelectedItem="{Binding SelectedPerson}" >
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <ContentControl Content="{Binding Name}">
                    </ContentControl>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</Window>