F#でWPF --- 可変個のコントロール
F#でWPFプロジェクトを作成する方法は下記記事を参照してください。
F#でWPF --- ウィンドウ表示 - 何でもプログラミング
作成するアプリケーション
ボタンを押す度、ランダムな位置に円シェイプを追加するアプリケーションを作成します。
コード(F#側)
コード内で利用しているDataContextは下記記事を参照してください
F#でWPF --- Elm Architectureを利用したMVVM - 何でもプログラミング
open System open System.Windows type Msg = AddCircle type Model = { Circles : Point list } let initialModel = { Circles = [] } let random = Random() let updateModel model msg = match msg with | AddCircle -> let p = Point(random.Next(100) |> double, random.Next(100) |> double) { model with Circles = p :: model.Circles } [<STAThread>] [<EntryPoint>] let main argv = let window = Application.LoadComponent(Uri("MainWindow.xaml", UriKind.Relative)) :?> Window window.DataContext <- DataContext(initialModel, updateModel, id) Application().Run(window) |> ignore 0
ItemsControl
可変個のコントロールを表示する際に、ItemsControlが利用できます。
基本的な使い方は下記のようなフォーマットになります。
<ItemsControl ItemsSource="{Binding Data}" > <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <!-- Controlを配置するPanel --> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate> <DataTemplate> <!-- Control --> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl>
可変個の円
Canvas上に可変個のEllipseを配置するにはこのようなコードになります。
Ellipseは全てItemContainerで包まれているため、Canvas.Leftを設定する場合はItemContainerStyleで設定する必要があります。
<ItemsControl ItemsSource="{Binding Circles}" > <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <Canvas /> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate> <DataTemplate> <Ellipse Width="10" Height="10" Fill="Orange" /> </DataTemplate> </ItemsControl.ItemTemplate> <ItemsControl.ItemContainerStyle> <Style> <Setter Property="Canvas.Left" Value="{Binding X}" /> <Setter Property="Canvas.Top" Value="{Binding Y}" /> </Style> </ItemsControl.ItemContainerStyle> </ItemsControl>
ItemContainerStyleを利用しない場合
EllipseをCanvasで包みます。
<ItemsControl ItemsSource="{Binding Circles}" > <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <Canvas /> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate> <DataTemplate> <Canvas> <Ellipse Canvas.Left="{Binding X}" Canvas.Right="{Binding Y}" Width="10" Height="10" Fill="Orange" /> </Canvas> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl>
Xaml全体
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Title="MainWindow" Height="180" Width="140"> <Grid> <ItemsControl ItemsSource="{Binding Circles}" Width="100" Height="100" Margin="10,10,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <Canvas /> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate> <DataTemplate> <Ellipse Width="10" Height="10" Fill="Orange" /> </DataTemplate> </ItemsControl.ItemTemplate> <ItemsControl.ItemContainerStyle> <Style> <Setter Property="Canvas.Left" Value="{Binding X}" /> <Setter Property="Canvas.Top" Value="{Binding Y}" /> </Style> </ItemsControl.ItemContainerStyle> </ItemsControl> <Button Content="追加" Command="{Binding AddCircle}" HorizontalAlignment="Left" Margin="10,115,0,0" VerticalAlignment="Top" Width="75"/> </Grid> </Window>