0
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 3 years have passed since last update.

WPFメモ Epoxy

Last updated at Posted at 2021-03-18

■概要

Epoxyを触ってみた。

■環境

  • Windows 10
  • Visual Studio Community 2019 Version 16.9.2
  • .NET 5.0
  • Epoxy.Wpf 0.15.0

■プロジェクト構成

ep01.png

■ソース

◇EpoxySample1.csproj

EpoxySample1.csproj
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net5.0-windows</TargetFramework>
    <UseWPF>true</UseWPF>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Epoxy.Wpf" Version="0.15.0" />
  </ItemGroup>

</Project>

◇MainWindow.xaml

MainWindow.xaml
<Window
    x:Class="EpoxySample1.Views.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:conv="clr-namespace:EpoxySample1.Converters"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:ep="https://github.com/kekyo/Epoxy"
    xmlns:local="clr-namespace:EpoxySample1.Views"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:vm="clr-namespace:EpoxySample1.ViewModels"
    Title="MainWindow"
    Width="500"
    Height="300"
    ResizeMode="CanResizeWithGrip"
    mc:Ignorable="d">
    <Window.Resources>
        <conv:InverseBooleanConverter x:Key="InverseBool" />
    </Window.Resources>

    <Window.DataContext>
        <vm:MainWindowViewModel />
    </Window.DataContext>

    <ep:EventBinder.Events>
        <ep:Event Name="Loaded" Command="{Binding WindowLoaded}" />
    </ep:EventBinder.Events>

    <Grid Background="WhiteSmoke">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition />
        </Grid.RowDefinitions>

        <StackPanel IsEnabled="{Binding IsBusy, Converter={StaticResource InverseBool}}">
            <TextBlock Margin="8,0" Text="パス" />
            <!--  検索するパス  -->
            <TextBox Margin="8,0" Text="{Binding TargetPath, UpdateSourceTrigger=PropertyChanged}" />
            <!--  検索ボタン  -->
            <Button
                Width="200"
                Margin="8"
                Padding="0,8"
                Command="{Binding SearchCommand}"
                Content="検索" />
        </StackPanel>

        <!--  指定されたパス直下のフォルダを一覧表示  -->
        <ListBox
            Grid.Row="1"
            Margin="8,8,8,16"
            ItemsSource="{Binding PathList}" />
    </Grid>
</Window>

◇MainWindowViewModel.cs

MainWindowViewModel.cs
using Epoxy;
using Epoxy.Synchronized;
using System.Collections.ObjectModel;
using System.Windows;

namespace EpoxySample1.ViewModels
{
    public sealed class MainWindowViewModel : ViewModel
    {
        /// <summary>
        /// 検索対象パス
        /// </summary>
        public string? TargetPath
        {
            get => GetValue();
            set
            { 
                SetValue(value);
                // 検索コマンドの実行可否 更新
                SearchCommand?.ChangeCanExecute();
            }
        }

        /// <summary>
        /// 処理中フラグ
        /// </summary>
        public bool IsBusy
        {
            get => GetValue();
            private set => SetValue(value);
        }

        /// <summary>
        /// 検索結果パス一覧
        /// </summary>
        public ObservableCollection<string>? PathList
        {
            get => GetValue<ObservableCollection<string>?>();
            private set => SetValue(value);
        }

        /// <summary>
        /// ウィンドウ起動時の処理
        /// </summary>
        public Command? WindowLoaded
        {
            get => GetValue();
            private set => SetValue(value);
        }

        /// <summary>
        /// 検索コマンド
        /// </summary>
        public Command? SearchCommand
        {
            get => GetValue();
            private set => SetValue(value);
        }

        /// <summary>
        /// コンストラクタ
        /// </summary>
        public MainWindowViewModel()
        {
            CreateCommands();
        }

        /// <summary>
        /// コマンド初期化
        /// </summary>
        private void CreateCommands()
        {
            // ウィンドウ起動
            WindowLoaded = Command.Factory.CreateSync<RoutedEventArgs>(e =>
            {
                IsBusy = false;
                TargetPath = @"C:\ProgramData";
                PathList = new ObservableCollection<string>();
            });

            // 検索
            SearchCommand = CommandFactory.Create(
                executeAsync: async () =>
                {
                    IsBusy = true;
                    PathList?.Clear();

                    var dir = new Models.Directory(TargetPath ?? "");
                    await foreach (var item in dir.GetItemsAsync())
                    {
                        PathList?.Add(item);
                    }

                    IsBusy = false;
                },
                canExecute: () =>
                {
                    // パスが空のときは無効
                    return !string.IsNullOrWhiteSpace(TargetPath);
                }
                );
        }
    }
}

◇Directory.cs

Directory.cs
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;

namespace EpoxySample1.Models
{
    public class Directory
    {
        private readonly string _basePath;

        public Directory(string basePath)
        {
            _basePath = basePath;
        }

        public async IAsyncEnumerable<string> GetItemsAsync()
        {
            var dirs = System.IO.Directory.EnumerateDirectories(
                _basePath, "*", SearchOption.TopDirectoryOnly);
            foreach (var dir in dirs)
            {
                // すぐ終わらないよう少し待つ
                await Task.Delay(100);
                // 1つ返す
                yield return dir;
            }
        }
    }

}

◇InverseBooleanConverter.cs

InverseBooleanConverter.cs
using Epoxy;

namespace EpoxySample1.Converters
{
    /// <summary>
    /// bool反転
    /// </summary>
    public class InverseBooleanConverter : ValueConverter<bool, bool>
    {
        public override bool TryConvert(bool from, out bool result)
        {
            result = !from;
            // 処理成功したらtrue
            return true;
        }
    }
}

■参考

0
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
0
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?