LoginSignup
0
0

More than 5 years have passed since last update.

Visual Studio / WPF > event > e.OriginalSourceの使用

Last updated at Posted at 2017-06-05
動作環境
Windows 7 Pro (32bit)
Microsoft Visual Studio 2017 Community
Sublime Text 2

http://gushwell.ldblog.jp/archives/52306698.html
を元に学習中。

MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
//
using System.Collections.ObjectModel;
using System.ComponentModel;

namespace _170605_t1450_collectionViewSource
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            _viewSource = listView1.ItemsSource as ICollectionView;
        }

        private GridViewColumnHeader _lastHeaderClicked = null;
        private ListSortDirection _lastDirection = ListSortDirection.Ascending;
        private ICollectionView _viewSource;

        private void GridViewColumnHeaderClickedHandler(object sender, RoutedEventArgs e)
        {
            GridViewColumnHeader clickedHeader = e.OriginalSource as GridViewColumnHeader;
            if (clickedHeader == null)
            {
                return;
            }
            if (clickedHeader.Role != GridViewColumnHeaderRole.Padding)
            {
                ListSortDirection direction = ListSortDirection.Ascending;
                if (clickedHeader == _lastHeaderClicked &&
                    _lastDirection == ListSortDirection.Ascending)
                {
                    direction = ListSortDirection.Descending;
                }
                string header = (clickedHeader.Column.DisplayMemberBinding as Binding).Path.Path;
                Sort(header, direction);
                _lastHeaderClicked = clickedHeader;
                _lastDirection = direction;
            }
        }

        private void Sort(string sortBy, ListSortDirection direciton)
        {
            SortDescription sd = new SortDescription(sortBy, direciton);
            _viewSource.SortDescriptions.Clear();
            _viewSource.SortDescriptions.Add(sd);
            _viewSource.Refresh();
        }
    }

    public class Book
    {
        public string Title { get; set; }
        public string Author { get; set; }
        public double Price { get; set; }
        public DateTime Date { get; set; }
    }

    public class BooksData
    {
        public BooksData()
        {
            BookList = new ObservableCollection<Book>();
            BookList.Add(new Book
            {
                Title = "リファクタリング",
                Author = "Martin Fowler",
                Date = new DateTime(2000, 5, 1),
                Price = 5040,
            });
            BookList.Add(new Book
            {
                Title = "アジャイルプラクティス",
                Author = "Venkat Subramaniam",
                Date = new DateTime(2007, 12, 22),
                Price = 2520,
            });
            BookList.Add(new Book
            {
                Title = "詳細 正規表現",
                Author = "Jeffrey Friedl",
                Date = new DateTime(2008, 4, 26),
                Price = 5040,
            });
        }
        public ObservableCollection<Book> BookList { get; set; }
    }
}
MainWindow.xaml
<Window x:Class="_170605_t1450_collectionViewSource.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"
        xmlns:local="clr-namespace:_170605_t1450_collectionViewSource"
        xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="720">
    <Window.Resources>
        <local:BooksData x:Key="books"/>
        <CollectionViewSource x:Key="myView" Source="{Binding Source={StaticResource books}, Path=BookList}">
            <CollectionViewSource.SortDescriptions>
                <scm:SortDescription PropertyName="Date"/>
                <scm:SortDescription PropertyName="Price"/>
            </CollectionViewSource.SortDescriptions>
        </CollectionViewSource>
    </Window.Resources>
    <Grid>
        <ListView Name="listView1" Margin="12"
                  ItemsSource="{Binding Source={StaticResource myView}}"
                  GridViewColumnHeader.Click="GridViewColumnHeaderClickedHandler"
                  >
            <ListView.View>
                <GridView>
                    <GridViewColumn DisplayMemberBinding="{Binding Path=Title}" Header="書籍名"/>
                    <GridViewColumn DisplayMemberBinding="{Binding Path=Author}" Header="著者"/>
                    <GridViewColumn DisplayMemberBinding="{Binding Path=Date, StringFormat=yyyy年MM月}" Header="出版月"/>
                    <GridViewColumn DisplayMemberBinding="{Binding Path=Price,StringFormat='#,###円'}" Header="価格"/>
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>
</Window>

気になった部分

上記のコードで気になったのは以下。

private void GridViewColumnHeaderClickedHandler(object sender, RoutedEventArgs e)
{
    GridViewColumnHeader clickedHeader = e.OriginalSource as GridViewColumnHeader;

senderでなくe.OriginalSource を使うのはなぜか。

ルーティング・イベント上の本質的なイベント発生源を取得するには、第1パラメータではなく RoutedEventArgs オブジェクトが提供する OriginalSource プロパティを使います。

        <ListView Name="listView1" Margin="12"
                  ItemsSource="{Binding Source={StaticResource myView}}"
                  GridViewColumnHeader.Click="GridViewColumnHeaderClickedHandler"
                  >
            <ListView.View>
                <GridView>
                    <GridViewColumn DisplayMemberBinding="{Binding Path=Title}" Header="書籍名"/>
                    <GridViewColumn DisplayMemberBinding="{Binding Path=Author}" Header="著者"/>

以下のように理解した。

ListView内のGridViewColumnHeaderをクリックした場合、senderにはListView が入ってしまう。本質的なイベント発生源(GridViewColumnHeader)を得るためにはe.OriginalSourceを使う。

その他の関連リンク: http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=47348&forum=7

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0