1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Elmish.WPFでオブジェクトのリストを雑にグリッドビューに流し込む

Posted at
  • 意図

    • Elmish.WPFを使用する
    • C#を使わずF#だけで完結させる
      • XAMLを埋め込みリソースとして保持して実行時にロードする
    • query式で出力を加工し、オブジェクトのプロパティをそのままカラムとして使用する
  • 備忘

    • XAMLまったく分からない
    • XAMLのデータバインディングを忘れても警告も何も出ないので注意する
    • F#のオブジェクトのリスト(のようなもの全般)はqueryのおかげで実質テーブル
    • dotnet publish -c Release でシングルバイナリ(160MB)を出力するようにfsprojを設定してある
      • SelfContained=falseにすればフレームワーク依存の実行ファイルができる(4MB)
wpf3.fsproj
 <Project Sdk="Microsoft.NET.Sdk">
 
   <PropertyGroup>
     <TargetFramework>net7.0-windows</TargetFramework>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
     <UseWpf>true</UseWpf>
     <OutputType>WinExe</OutputType>
 
     <SelfContained>true</SelfContained>
    
     <PublishSingleFile>true</PublishSingleFile>
     <RuntimeIdentifier>win-x64</RuntimeIdentifier>
     <IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
 
   </PropertyGroup>
 
   <ItemGroup>
     <PackageReference Include="Elmish.WPF" Version="3.5.8" />
   </ItemGroup>
   
   <ItemGroup>
     <Resource Include="MainWindow.xaml" />
     <Compile Include="Library.fs" />
   </ItemGroup>
   
 </Project>
Library.fs
 module MainWindow
 
 module hoge =
     open System.IO
 
     let hoge1 () = // グリッドビューに表示したいオブジェクトのseqを得る関数
         let desktop =
             System.Environment.GetFolderPath System.Environment.SpecialFolder.DesktopDirectory
 
         let files =
             System.IO.Directory.EnumerateFiles(desktop, "*.txt", EnumerationOptions(RecurseSubdirectories = false))
             |> Seq.map (fun path -> FileInfo path)
 
         query {
             for file in files do
                 select
                     {| name = file.Name
                        size = file.Length |}
         }
         |> Seq.cast<obj>
 
 
 module gui =
     open Elmish.WPF
 
     type Model = { GridItemList: obj seq }
 
     type Msg =
         | Load
         | Reset
 
     let init = { GridItemList = [] }
 
     let canReset = (<>) init
 
     let update msg m =
         match msg with
         | Load -> { m with GridItemList = hoge.hoge1 () }
         | Reset -> init
 
     let bindings () : Elmish.WPF.Binding<Model, Msg> list =
         [ "Load" |> Binding.cmd Load
           "Reset" |> Binding.cmdIf (Reset, canReset)
           "GridItemList" |> Binding.oneWay (fun m -> m.GridItemList) ]
 
     let designVm = Elmish.WPF.ViewModel.designInstance init (bindings ())
 
 
     let main window =
         Elmish.WPF.Program.mkSimpleWpf (fun () -> init) update bindings
         |> Program.runWindow window
 
 
 open System.Windows.Markup
 open System.Windows.Controls
 open System.Windows
 
 
 [<EntryPoint; System.STAThreadAttribute>]
 let entryPoint args =
     let uri = new System.Uri(@"/MainWindow.xaml", System.UriKind.Relative)
     let stream = Application.GetResourceStream(uri).Stream
     let window = XamlReader.Load(stream) :?> System.Windows.Window
     gui.main window
MainWindow.xaml
 <Window x:Class="System.Windows.Window"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:vm="clr-namespace:Elmish.WPF.Samples.SingleCounter;assembly=SingleCounter.Core"
         Title="Sample"
         Height="200"
         Width="500"
         WindowStartupLocation="CenterScreen"
         mc:Ignorable="d"
         d:DataContext="{x:Static vm:Program.designVm}">
 
 
 <Grid>
     <Grid.RowDefinitions>
         <RowDefinition Height="32" />  
         <RowDefinition Height="*" />  
     </Grid.RowDefinitions>
 
     <StackPanel Grid.Row="0"  Orientation="Horizontal">
         <Button Width="80" Margin="5,5,10,5" Content="Load" Command="{Binding Load}" />
         <Button Width="80" Margin="0,5,10,5" Content="Reset" Command="{Binding Reset}" />
     </StackPanel>
 
     <DataGrid Grid.Row="1" x:Name="DataGrid1"
         Width="Auto" Height="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
         ItemsSource="{Binding GridItemList, Mode=OneWay}"
         AutoGenerateColumns="true"
         IsReadOnly="true" >
     </DataGrid>
 
 </Grid>
 
 </Window>
1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?