忍者ブログ

Memeplexes

プログラミング、3DCGとその他いろいろについて

WPFで列挙型の表示(DataTemplateSelector)

 WPFの話です。

さて以下のような列挙型があり、
それをWPFで表示したくなったとします。

public enum FigureType
{
    Ellipse,
    Rectangle,
    Triangle
}
3つの値はそれぞれ図形のタイプを表しています。
丸、四角、三角です。

例えば「この中から一つ図形をユーザーに選ばせたい」という状況を考えてください。

すると、WPFでは全体として次のようになるでしょう。
(全体として、と言いましたがMainWindow.csとMainWindow.xamlだけです。
App.xaml、App.csはデフォルトのままなので割愛します。)


C#
using System.Windows;

namespace DataTemplateSelectorDemo
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            figuresView.ItemsSource = System.Enum.GetValues(typeof(FigureType));
        }
    }

    public enum FigureType
    {
        Ellipse,
        Rectangle,
        Triangle
    }
}

XAML
<Window x:Class="DataTemplateSelectorDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">

    <ListBox x:Name="figuresView"/>
    
</Window>


この結果がどうなるかというと、以下のようなぐあいです。
dataTemplateSelectorWithoutSelector.png

リストボックス中に3つの選択肢が出てきます!
リストボックスなのでマウスでクリックするとそれ相応のイベントが発生し
選択した図形をもとにプログラムを書くことができます。

しかしここで表示されるのはあくまでも文字なので、
ちょっと使いにくいと考える人もいるでしょう。

Ellipse, Rectangle, Triangleよりも
○、□、△のほうが直感的です。

DataTemplateSelectorを使う

では列挙型をもとに図形を表示するにはどうすればいいでしょうか?
WPFではSystem.Windows.Controls.DataTemplateSelectorを利用するとできます。

(別の方法もあるのですが)
これを使うと以下のようになります。

C#
using System.Windows;
using System.Windows.Controls;

namespace DataTemplateSelectorDemo
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            figuresView.ItemsSource = System.Enum.GetValues(typeof(FigureType));
        }
    }

    public enum FigureType
    {
        Ellipse,
        Rectangle,
        Triangle
    }


    public class FigureTypeDataTemplateSelector : DataTemplateSelector     {
public DataTemplate EllipseDataTemplate { get; set; }
public DataTemplate RectangleDataTemplate { get; set; }
public DataTemplate TriangleDataTemplate { get; set; }

public override DataTemplate SelectTemplate(
object item,
DependencyObject container
)
{
if (!(item is FigureType)) return null;

switch ((FigureType)item)
{
case FigureType.Ellipse:
return EllipseDataTemplate;
case FigureType.Rectangle:
return RectangleDataTemplate;
case FigureType.Triangle:
return TriangleDataTemplate;
default: return null;
}
}
}
}

XAML
<Window x:Class="DataTemplateSelectorDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:model="clr-namespace:DataTemplateSelectorDemo"
        Title="MainWindow" Height="350" Width="525">

    <ListBox x:Name="figuresView" ItemTemplateSelector="{DynamicResource templateSelector}"/>

    <Window.Resources>
<DataTemplate x:Key="MyEllipseDataTemplate">
<Ellipse Stroke="Black" Width="100" Height="100"/>
</DataTemplate>
<DataTemplate x:Key="MyRectangleDataTemplate">
<Rectangle Stroke="Black" Width="150" Height="100"/>
</DataTemplate>
<DataTemplate x:Key="MyTriangleDataTemplate">
<Polygon Stroke="Black" Points="100,0 0,100 200,100"/>
</DataTemplate>

<model:FigureTypeDataTemplateSelector
x:Key="templateSelector"
EllipseDataTemplate="{StaticResource MyEllipseDataTemplate}"
RectangleDataTemplate="{StaticResource MyRectangleDataTemplate}"
TriangleDataTemplate="{StaticResource MyTriangleDataTemplate}"
/> </Window.Resources>
</Window>


DataTemplateSelectorは、「どの値の時にどのように表示するか」を決定することができます。
丸の時には○を表示するように、四角の時には□を表示するように、三角の時には△を表示するようにしたいものです。
そういったことを実際に決定するのがDataTemplateSelector.SelectTemplate()メソッドで、
上のコードではswitchで場合分けしてデータの表示方法(DataTemplate)をreturnしています。

結果はこうなります。

dataTemplateSelectorDemoWithFigure.jpg


リストボックス中に図形が表示されました!

ここでは列挙型を表示しましたが、
もちろん、DataTemplateSelectorは列挙体だけでなくintなど他の値であっても使えるクラスです。























拍手[1回]

PR