LoginSignup
0
1

More than 1 year has passed since last update.

こんな感じのサンプルが作れます!

win7_export.gif

参考記事

今回はITmediaさん連載記事のwpfチュートリアルをアレンジしています!
基本的にはサイトに書いてある内容そのままです.

記事の内容として古くなっている部分,わかりにくい部分を補う形で説明します.

画面の構成

windows7のエクスプローラーをwpfアプリで再現しようと考えた時に,画面の構成は以下のように分解しました.

image.png

データのコレクション用処理

MainViewModel.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.ObjectModel;
using System.ComponentModel;


namespace Windows7_Explorer_WPF_Tutorial
{
    public class MainViewModel : INotifyPropertyChanged
    {
        public MainViewModel()
        {
            ObservableCollection<File> files = new ObservableCollection<File>();

            files.Add(new File() { Name = "apple.png", ImageSize = "256 × 256", Type = "PNG イメージ", Size = "256 KB", CreateDate = "20XX/XX/XX XX:XX" });
            ~略~

            Files = files;
            SelectedFile = files[0];
        }

        public ObservableCollection<File> Files { get; set; }
        private File selectedFile;
        public File SelectedFile
        {
            get
            {
                return selectedFile;
            }
            set
            {
                selectedFile = value;
                NotifyPropertyChanged("SelectedFile");
            }
        }

        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
        #endregion
    }
}

File.cs
namespace Windows7_Explorer_WPF_Tutorial
{
    public class File
    {
        public string Name { get; set; }
        public string Type { get; set; }
        public string Size { get; set; }
        public string ImageSize { get; set; }
        public string CreateDate { get; set; }
    }
}

ヘッダー部分

MainWindow.xaml
    <Border Grid.Row="0" BorderThickness="0,0,0,1.5" BorderBrush="#FFA0AFC3">
    <StackPanel Orientation="Horizontal">
        <StackPanel.Background>
            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                <GradientStop Color="#FFFAFCFD" Offset="0" />
                <GradientStop Color="#FFE4EFFB" Offset="1" />
                <GradientStop Color="#FFDCE6F4" Offset="0.5" />
                <GradientStop Color="#FFE6F0FA" Offset="0.499" />
            </LinearGradientBrush>
        </StackPanel.Background>
        <StackPanel.Resources>
            <Style x:Key="ButtonStyle" TargetType="Button">
                <Setter Property="Margin" Value="18,0,12,0" />
                <Setter Property="Foreground" Value="#FF1E395B" />
                <Setter Property="Background" Value="{x:Null}" />
                <Setter Property="BorderBrush" Value="{x:Null}" />
            </Style>
        </StackPanel.Resources>
        <Button Content="整理" Style="{StaticResource ButtonStyle}"/>
        <Button Content="開く" Style="{StaticResource ButtonStyle}"/>
        <Button Content="印刷" Style="{StaticResource ButtonStyle}"/>
        <Button Content="書き込む" Style="{StaticResource ButtonStyle}"/>
        <Button Content="新しいフォルダー" Style="{StaticResource ButtonStyle}"/>
    </StackPanel>
    </Border>

ディレクトリ表示部分

今回はツリービューを使っています.
また,「ディレクトリ表示部分」と「ファイルリスト」のエリアを分割するためにGridSplitter要素を用いています.

MainWindow.xaml

    <TreeView  Grid.Column="0" BorderThickness="0,0,0,0" Margin="0,0,1,0" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
        <TreeViewItem Header="コンピューター" IsExpanded="True">
            <TreeViewItem Header="(C:)" IsExpanded="True">
                <TreeViewItem Header="くだもの"/>
            </TreeViewItem>
        </TreeViewItem>
    </TreeView>
    <GridSplitter Grid.Column="0" HorizontalAlignment="Right" Width="1" Background="#FFD6E5F5" IsTabStop="False"/>

ファイルリスト部分

はじめに,要素のスタイル表示を加工します.
親のGride要素に,Grid.Resourceを要素として定義することで,全体にスタイルを適用します.
このスタイルは,フッター部分でも再利用します.

MainWindow.xaml
        <Grid.Resources>
            <Style TargetType="TextBlock" x:Key="label1">
                <Setter Property="Margin" Value="4,4,2,-2"/>
                <Setter Property="Foreground" Value="#FF5A6779" />
                <Setter Property="Width" Value="60" />
                <Setter Property="TextAlignment" Value="Right" />
            </Style>
            <Style TargetType="TextBlock" x:Key="label2">
                <Setter Property="Margin" Value="4,4,2,-2"/>
                <Setter Property="Foreground" Value="#FF1E395B"/>
            </Style>
            <Style TargetType="ListBoxItem">
                <Setter Property="HorizontalContentAlignment" Value="Stretch" />
            </Style>
        </Grid.Resources>

ファイル全体のリスト表示をするために,ListBoxを用いています.
リストボックスの中にImageBoxとStackPanelを格納しています.

さらに,リストボックス内の配置をGridで要素分けして配置します.

MainWindow.xaml
 <ListBox  Grid.Column="1" BorderThickness="0,0,0,0" Margin="0,0,1,0" ItemsSource="{Binding Files}" SelectedValue="{Binding SelectedFile, Mode=TwoWay}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Border BorderThickness="0,0,0,1" BorderBrush="#FFDCDCDC" Margin="17,0,10,0">
                    <Grid Height="53" HorizontalAlignment="Stretch">

                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="180"/>
                            <ColumnDefinition />
                            <ColumnDefinition Width="180" />
                        </Grid.ColumnDefinitions>
                        <Border Background="White" Margin="0,7,0,18" VerticalAlignment="Center" HorizontalAlignment="Center">
                            <Border.Effect>
                                <DropShadowEffect Color="Gray" Direction="-45" Opacity="0.5" ShadowDepth="2" />
                            </Border.Effect>
                            <Image Source="{Binding Name}" Width="29" />
                        </Border>
                        <TextBlock Grid.Column="1" Text="{Binding Name}" FontSize="14.6666666666667" Margin="11,4" />
                        <StackPanel Grid.Column="2" Margin="0,5" HorizontalAlignment="Left" >
                            <StackPanel Orientation="Horizontal">
                                <TextBlock Text="種類:" Style="{StaticResource label1}" />
                                <TextBlock Text="{Binding Type}" Style="{StaticResource label2}" />
                            </StackPanel>
                            <StackPanel Orientation="Horizontal">
                                <TextBlock Text="大きさ:" Style="{StaticResource label1}" />
                                <TextBlock Text="{Binding ImageSize}" Style="{StaticResource label2}" />
                            </StackPanel>
                        </StackPanel>
                        <StackPanel Grid.Column="3" Margin="0,5">
                            <StackPanel Orientation="Horizontal">
                                <TextBlock Text="撮影日時:" Style="{StaticResource label1}" />
                                <TextBlock Text="{Binding CreateDate}" Style="{StaticResource label2}" />
                            </StackPanel>
                            <StackPanel Orientation="Horizontal">
                                <TextBlock Text="サイズ:" Style="{StaticResource label1}" />
                                <TextBlock Text="{Binding Size}" Style="{StaticResource label2}" />
                            </StackPanel>
                        </StackPanel>
                    </Grid>
                </Border>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    <GridSplitter Grid.Column="1" HorizontalAlignment="Right" Width="1" Background="#FFD6E5F5" IsTabStop="False"/>

データバインディングはxamlファイルに直接記述することで定義もできますが,視覚的に設定することもできます.
例えば,ListBoxのItemSourceにバインディングソースにFilesクラスを設定してみます.

ItemsSource="{Binding Files}"

ListBoxを選択した後,ItemSourceを編集するために,新規ボタンとなりの「□」ボタンをクリックします.

image.png

プロパティウィンドウが表示された後,データバインディングの作成ボタンを押します.

image.png

さらに,データバインディング編集用ウィンドウが開けば,パスにFilesクラスを指定します.

image.png

リストボックスの子要素として,テキストボックスやイメージボックスを入れ込んでいます.
さらに,スタックパネルのオリエンテーションを,Horizontal(水平)方向に設定しています.

< StackPanel Orientation="Horizontal" >

image.png

StackPanelを列として重ね合わせるので,Vertical(垂直)方向に設定してみた様子です.

< StackPanel Orientation="Vertical" >

image.png

スタックパネルのオリエンテーションを,Vertical(垂直)方向に設定すると,Marginの影響で崩れてしまいます.

ファイル詳細部分

画像を単体で表示します.
画像にエフェクトをつけるために,Border要素で囲みます.
Border.effect属性にDropShadowEffectクラスを渡して,画像に影を生成します.

MainWindow.xaml
    <Border Grid.Column="2"  Margin="16" Background="White" VerticalAlignment="Center" HorizontalAlignment="Center" >
        <Border.Effect>
            <DropShadowEffect Color="#FFAFAFAF" Direction="-45" Opacity="0.5" ShadowDepth="4" />
        </Border.Effect>
        <Image Source="{Binding SelectedFile.Name}"/>
    </Border>

フッター部分

フッター部分でも,画像部分とテキスト表示部分とに列を分けています.
ファイルリストエリアでも,StackPanelを配置しましたが,その際に列を意識しなければなりませんでした.
ここでは,WrapPanelを用いてStackPanelを表示しています.
要素がWrappanelの領域の範囲を超えると,自動的に要素を次の(列.行)に送ることができます.

MainWindow.xaml
    <Grid Grid.Row="2" Background="#FFF1F5FB" DataContext="{Binding SelectedFile}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="292*"/>
        </Grid.ColumnDefinitions>
        <Border Grid.Column="0" Margin="20, 6, 20 ,7"  Background="#FFF1F5FB" VerticalAlignment="Center" HorizontalAlignment="Center">
            <Border.Effect>
                <DropShadowEffect Color="Gray" Direction="-45" Opacity="0.5" ShadowDepth="2" />
            </Border.Effect>
            <Image MinWidth="40" MaxWidth="238" Source="{Binding Name}" />
        </Border>
        <WrapPanel Grid.Column="1" Orientation="Vertical">
            <TextBlock Margin="0,4,0,0" FontSize="13.33333333" Text="{Binding Name}"/>
            <TextBlock Foreground="#FF5A6779" Text="{Binding Type}"/>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="撮影日時:" Style="{StaticResource label1}"/>
                <TextBlock Text="{Binding CreateDate}" Style="{StaticResource label2}"/>
            </StackPanel>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="大きさ:" Style="{StaticResource label1}"/>
                <TextBlock Text="{Binding ImageSize}" Style="{StaticResource label2}"/>
            </StackPanel>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="サイズ:" Style="{StaticResource label1}"/>
                <TextBlock Text="{Binding Size}" Style="{StaticResource label2}"/>
            </StackPanel>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="作成日時:" Style="{StaticResource label1}"/>
                <TextBlock Text="{Binding CreateDate}" Style="{StaticResource label2}"/>
            </StackPanel>
        </WrapPanel >
    </Grid>

プロジェクトに画像を読み込ませる.

「プロジェクト」→「既存の項目の追加(ショートカット:Shift+Alt+A)」でプロジェクトに画像等のリソースを追加できます.

画像が正しく読み込まれない時は,ビルドアクションを変更してください.
ビルドアクションの項目を「埋め込みリソース」か,「リソース」に設定することで,画像が読み込まれるようになります.

image.png

image.png

おわりに

表面的なUIの実装だけで,まだボタンやツリービュー押下ジの処理を組んでいません.
今後は,処理部分も組んでみようと思います.

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