fc2ブログ

【Material Design Toolkit】 Button2

 Material Design Toolkitが更新されボタンにバッチを表示する機能とプログレス表示機能が追加されました。
<StackPanel>
    <materialDesign:Badged Badge="Badge" Margin="10">
        <Button Content="Button"/>
    </materialDesign:Badged>

    <Button Content="Progress Button" Margin="10"
            materialDesign:ButtonProgressAssist.Minimum="0"
            materialDesign:ButtonProgressAssist.Maximum="100"
            materialDesign:ButtonProgressAssist.Value="60"/>

    <StackPanel Orientation="Horizontal">
        <Button Style="{StaticResource MaterialDesignFloatingActionButton}"
                Content="A" Margin="10"
                materialDesign:ButtonProgressAssist.IsIndicatorVisible="True"
                materialDesign:ButtonProgressAssist.Minimum="0"
                materialDesign:ButtonProgressAssist.Maximum="100"
                materialDesign:ButtonProgressAssist.Value="60"/>
        <Button Style="{StaticResource MaterialDesignFloatingActionButton}"
                Content="B" Margin="10"
                materialDesign:ButtonProgressAssist.IsIndicatorVisible="True"
                materialDesign:ButtonProgressAssist.IsIndeterminate="True"
                materialDesign:ButtonProgressAssist.Value="30"/>
        <Button Style="{StaticResource MaterialDesignFloatingActionButton}"
                Content="C" Margin="10"
                materialDesign:ButtonProgressAssist.IsIndicatorVisible="True"
                materialDesign:ButtonProgressAssist.IsIndeterminate="True"
                materialDesign:ButtonProgressAssist.Value="30"
                materialDesign:ButtonProgressAssist.IndicatorBackground="Red"
                materialDesign:ButtonProgressAssist.IndicatorForeground="Yellow"/>
        <Button Style="{StaticResource MaterialDesignFloatingActionMiniDarkButton}"
                Content="C" Margin="10"
                materialDesign:ButtonProgressAssist.IsIndicatorVisible="True"
                materialDesign:ButtonProgressAssist.IsIndeterminate="True"
                materialDesign:ButtonProgressAssist.Value="30"/>
    </StackPanel>
</StackPanel>
 このコードを実行すると以下の様になります。
MaterialDesign追加ボタン
 Badgedコンテンツ内にボタンを配置することでボタンの右上にバッチを表示することができます。
 バッチに表示する内容はBadgedのBadgeプロパティで指定できます。

 ボタンにプログレス機能を追加する場合はButtonProgressAssistを利用します。
 通常のボタン(四角ボタン)の場合はボタンの背景色を変化させて状況通知を行います。
 進捗状況はButtonProgressAssistのMinimum、Maximum、Valueで指定できます。
 四角ボタンの場合はIndeterminate機能は使用できません。

 丸ボタンの場合はButtonProgressAssist.IsIndicatorVisibleをTrueにしないとプログレスリングが表示されません。
 四角ボタンの時と同様にuttonProgressAssistのMinimum、Maximum、Valueを指定して状況通知を行えます。
 丸ボタンの場合はButtonProgressAssist.IndicatorBackgroundとButtonProgressAssist.IndicatorForegroundを指定することでプログレスリングの色を自由に指定できます。
 また、IsIndeterminateをTrueにすることでリングがぐるぐる回るアニメーションが表示されます。
 丸ボタンのプログレス機能は小さい丸ボタンでも使用可能です。 
スポンサーサイト



テーマ : プログラミング
ジャンル : コンピュータ

【Material Design Toolkit】 TabControl (Dragablz)

 Material Design Toolkitにはタブコントロールが定義されていません。
 Material Design Toolkitのデザインに合わせたタブコントロールが必要な場合はDragablzライブラリを使用します。
 DragablzライブラリはMaterial Design Toolkitと同じ作者が作成した高機能なタブコントロールでタブアイテムを別ウインドウとして切り離したり、タブアイテムを上下左右に並べて表示したりできます。
 Dragablzを使用する場合はNuGetでインストールが必要です。
 また、Dragablzの見た目をMaterial Design Toolkitと合わせるためにDragablz用の設定を行う必要があります。
<Application x:Class="MdDemo.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:dragablz="clr-namespace:Dragablz;assembly=Dragablz"
             StartupUri="Views\MainWindow.xaml"
             Startup="Application_Startup">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml" />
                <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
                <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.DeepPurple.xaml" />
                <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.Lime.xaml" />

                <!-- Dragablz Material Design -->
                <ResourceDictionary Source="pack://application:,,,/Dragablz;component/Themes/materialdesign.xaml"/>
            </ResourceDictionary.MergedDictionaries>

            <!-- Dragablz Material Design -->
            <Style TargetType="{x:Type dragablz:TabablzControl}" BasedOn="{StaticResource MaterialDesignTabablzControlStyle}" />
        </ResourceDictionary>
    </Application.Resources>
</Application>
 Dragablzを使用する場合はApp.xamlでMaterial Design Toolkit用の設定と合わせてDragablz用設定を指定する必要があります。

<Window x:Class="MdDemo.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="clr-namespace:MdDemo.ViewModels"
        xmlns:dragablz="clr-namespace:Dragablz;assembly=Dragablz"
        xmlns:dockablz="clr-namespace:Dragablz.Dockablz;assembly=Dragablz"
        TextElement.Foreground="{DynamicResource MaterialDesignBody}"
        TextElement.FontWeight="Regular"
        TextElement.FontSize="14"
        TextOptions.TextFormattingMode="Ideal" 
        TextOptions.TextRenderingMode="Auto"        
        Background="{DynamicResource MaterialDesignPaper}"
        FontFamily="{StaticResource MaterialDesignFont}"
        Title="MainWindow" Height="350" Width="525">
    
    <Window.DataContext>
        <vm:MainWindowViewModel/>
    </Window.DataContext>

    <dockablz:Layout>
        <dragablz:TabablzControl FixedHeaderCount="1" ConsolidateOrphanedItems="True">
            <dragablz:TabablzControl.InterTabController>
                <dragablz:InterTabController />
            </dragablz:TabablzControl.InterTabController>

            <TabItem Header="Item1">
                <TextBlock Text="Tab Item1" FontSize="32"/>
            </TabItem>
            <TabItem Header="Item2">
                <TextBlock Text="Tab Item2" FontSize="32"/>
            </TabItem>
            <TabItem Header="Item3">
                <TextBlock Text="Tab Item3" FontSize="32"/>
            </TabItem>
        </dragablz:TabablzControl>
    </dockablz:Layout>
</Window>
 このコードを実行すると以下の様になります。
Dragablz_TabControl.png
 タブアイテムを上下左右に並べて表示したい場合はdockablz:Layout内にdragablz:TabablzControlを設置し、dragablz:TabablzControl.InterTabControllerを設定する必要があります。
 こうすればタブアイテムをドラッグしてタブアイテムの配置を変更できるようになります。
Dragablz_タブアイテムレイアウト位置指定
 タブアイテムをドラッグすると上の図のようにレイアウト範囲の上下左右にグレーの半円が表示されます。
 ドラッグ中のタブアイテムをグレーの半円部分にドロップするとレイアウトが変更されます。
 以下の図はTabItem2をTabItem1の下に表示した後、TabItem3を右側に配置した図です。
Dragablz_タブアイテムレイアウト変更後
 タブアイテムのレイアウト機能が必要ない場合はdockablz:Layoutは必要ありません。

 タブアイテムを別ウインドウとして切り出す場合はdragablz:TabablzControlにdragablz:TabablzControl.InterTabControllerを設定します。
 タブアイテムをドラッグすることで別ウインドウとして切り離すことが可能です。
Dragablz_タブアイテム切り離し
 また、切り離したウインドウのタブをドラッグして元のウインドウのタブヘッダー上にドロップすることで元に戻すこともできます。
(ウインドウ上部をドラッグしている場合は戻せません。タブのヘッダーをドラッグしてください。)
 dragablz:TabablzControlのConsolidateOrphanedItemsプロパティをTrueにすると切り離したタブウインドウを閉じると元のウインドウに再び表示されるようになります。
 FixedHeaderCountプロパティを指定すると、指定した数のタブアイテムがドラッグできなくなります。(レイアウトの変更やウインドウ切り離し、タブアイテムの並べ替えができなくなります)

 以下の様にLayoutもTabablzControl.InterTabControllerも使用しなければシンプルなタブコントロールとして使用できます。
<dragablz:TabablzControl >
    <TabItem Header="Item1">
        <TextBlock Text="Tab Item1" FontSize="32"/>
    </TabItem>
    <TabItem Header="Item2">
        <TextBlock Text="Tab Item2" FontSize="32"/>
    </TabItem>
    <TabItem Header="Item3">
        <TextBlock Text="Tab Item3" FontSize="32"/>
    </TabItem>
</dragablz:TabablzControl>
 

テーマ : プログラミング
ジャンル : コンピュータ

【Material Design Toolkit】 Transitioner

 Transitionerを使用するとパワーポイントのスライドショーの様にスライドを1枚づつ表示することができます。
 処理が複数のステップに分かれている時等に使用します。
<Window x:Class="MdDemo.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="clr-namespace:MdDemo.ViewModels"
        xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
        TextElement.Foreground="{DynamicResource MaterialDesignBody}"
        TextElement.FontWeight="Regular"
        TextElement.FontSize="13"
        TextOptions.TextFormattingMode="Ideal" 
        TextOptions.TextRenderingMode="Auto"        
        Background="{DynamicResource MaterialDesignPaper}"
        FontFamily="{StaticResource MaterialDesignFont}"
        Title="MainWindow" Height="350" Width="525">
    
    <Window.DataContext>
        <vm:MainWindowViewModel/>
    </Window.DataContext>

    <materialDesign:Transitioner SelectedIndex="0">
        <materialDesign:TransitionerSlide
            OpeningEffect="{materialDesign:TransitionEffect Kind=FadeIn}">
            <StackPanel Background="AliceBlue">
                <TextBlock Text="スライド1" FontSize="64"/>
                <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
                    <Button Content="次へ" Width="100"
                            Command="{x:Static materialDesign:Transitioner.MoveNextCommand}"/>
                    <Button Content="最後へ" Width="100"
                            Command="{x:Static materialDesign:Transitioner.MoveLastCommand}"/>
                </StackPanel>
            </StackPanel>
        </materialDesign:TransitionerSlide>

        <materialDesign:TransitionerSlide
            OpeningEffect="{materialDesign:TransitionEffect Kind=SlideInFromLeft, Duration=0:0:2}">
            <StackPanel Background="LightSteelBlue">
                <TextBlock Text="スライド2" FontSize="64"/>
                <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
                    <Button Content="前へ" Width="100"
                            Command="{x:Static materialDesign:Transitioner.MovePreviousCommand}"/>
                    <Button Content="次へ" Width="100"
                            Command="{x:Static materialDesign:Transitioner.MoveNextCommand}"/>
                </StackPanel>
            </StackPanel>
        </materialDesign:TransitionerSlide>

        <StackPanel Background="CornflowerBlue">
            <TextBlock Text="スライド3" FontSize="64"/>
            <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
                <Button Content="最初へ" Width="100"
                            Command="{x:Static materialDesign:Transitioner.MoveFirstCommand}"/>
            </StackPanel>
        </StackPanel>
    </materialDesign:Transitioner>
</Window>
 これを実行し、スライドを移動させると以下の様に表示されます。
Transitioner.png
 Transitioner領域にスライドが表示されます。
 SselectedIndexプロパティで最初に表示するスライドを指定しています。
 あとはTransitioner以下にスライドを表示順に定義していきます。
 TransitionerSlideを使用する場合はOpeningEffectでスライドを表示する際のエフェクトを指定できます。
 TransitionEffectにはExpandIn、FadeIn、None、SlideInFromBottom、SlideInFromLeft、SlideInFromRight、SlideInFromTopの7種類があります。
 また、Durationを指定することでスライド表示エフェクトの表示時間を変更することもできます。
 TransitionerSlideを使用いない場合(サンプルコードのスライド3)はエフェクトにはNoneが使用されます。

 スライドの移動はコマンドを使用します。
 スライド移動用コマンドは以下の4つが用意されています。
 materialDesign:Transitioner.MoveNextCommand : 次のスライドを表示する
 materialDesign:Transitioner.MovePreviousCommand : 前のスライドを表示する
 materialDesign:Transitioner.MoveFirstCommand : 最初のスライドを表示する
 materialDesign:Transitioner.MoveLastCommand : 最後のスライドを表示する

テーマ : プログラミング
ジャンル : コンピュータ

【Material Design Toolkit】 Drawer

 Drawerは画面(正確にはDrawerHost)の上下左右からせり出してくるコントロールです。(メニュー表示等でよく見かけると思います。)
 DrawerのOpen、Close用のコマンドも用意されているのでかなり簡単に扱うことができます。
<materialDesign:DrawerHost Margin="10" BorderThickness="2" BorderBrush="Black">
    <materialDesign:DrawerHost.LeftDrawerContent>
        <StackPanel>
            <TextBlock Text="Left Drawer"/>
            <Button Content="閉じる" Style="{DynamicResource MaterialDesignFlatButton}"
                    Command="{x:Static materialDesign:DrawerHost.CloseDrawerCommand}"
                    CommandParameter="{x:Static Dock.Left}"/>
            <Button Content="全て閉じる" Style="{DynamicResource MaterialDesignFlatButton}"
                    Command="{x:Static materialDesign:DrawerHost.CloseDrawerCommand}"/>
        </StackPanel>
    </materialDesign:DrawerHost.LeftDrawerContent>
    <materialDesign:DrawerHost.TopDrawerContent>
        <StackPanel>
            <TextBlock Text="Top Drawer"/>
            <Button Content="閉じる" Style="{DynamicResource MaterialDesignFlatButton}"
                    Command="{x:Static materialDesign:DrawerHost.CloseDrawerCommand}"
                    CommandParameter="{x:Static Dock.Top}"/>
            <Button Content="全て閉じる" Style="{DynamicResource MaterialDesignFlatButton}"
                    Command="{x:Static materialDesign:DrawerHost.CloseDrawerCommand}"/>
        </StackPanel>
    </materialDesign:DrawerHost.TopDrawerContent>
    <materialDesign:DrawerHost.RightDrawerContent>
        <StackPanel>
            <TextBlock Text="Right Drawer"/>
            <Button Content="閉じる" Style="{DynamicResource MaterialDesignFlatButton}"
                    Command="{x:Static materialDesign:DrawerHost.CloseDrawerCommand}"
                    CommandParameter="{x:Static Dock.Right}"/>
            <Button Content="全て閉じる" Style="{DynamicResource MaterialDesignFlatButton}"
                    Command="{x:Static materialDesign:DrawerHost.CloseDrawerCommand}"/>
        </StackPanel>
    </materialDesign:DrawerHost.RightDrawerContent>
    <materialDesign:DrawerHost.BottomDrawerContent>
        <StackPanel>
            <TextBlock Text="Bottom Drawer"/>
            <Button Content="閉じる" Style="{DynamicResource MaterialDesignFlatButton}"
                    Command="{x:Static materialDesign:DrawerHost.CloseDrawerCommand}"
                    CommandParameter="{x:Static Dock.Bottom}"/>
            <Button Content="全て閉じる" Style="{DynamicResource MaterialDesignFlatButton}"
                    Command="{x:Static materialDesign:DrawerHost.CloseDrawerCommand}"/>
        </StackPanel>
    </materialDesign:DrawerHost.BottomDrawerContent>

    <Grid HorizontalAlignment="Center" VerticalAlignment="Center">
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>

        <Button Grid.Row="1" Grid.Column="0"
                Command="{x:Static materialDesign:DrawerHost.OpenDrawerCommand}"
                CommandParameter="{x:Static Dock.Left}">
            <materialDesign:PackIcon Kind="ArrowLeft"/>
        </Button>
        <Button Grid.Row="0" Grid.Column="1"
                Command="{x:Static materialDesign:DrawerHost.OpenDrawerCommand}"
                CommandParameter="{x:Static Dock.Top}">
            <materialDesign:PackIcon Kind="ArrowUp"/>
        </Button>
        <Button Grid.Row="1" Grid.Column="2"
                Command="{x:Static materialDesign:DrawerHost.OpenDrawerCommand}"
                CommandParameter="{x:Static Dock.Right}">
            <materialDesign:PackIcon Kind="ArrowRight"/>
        </Button>
        <Button Grid.Row="2" Grid.Column="1"
                Command="{x:Static materialDesign:DrawerHost.OpenDrawerCommand}"
                CommandParameter="{x:Static Dock.Bottom}">
            <materialDesign:PackIcon Kind="ArrowDown"/>
        </Button>
        <Button Grid.Row="1" Grid.Column="1"
                Command="{x:Static materialDesign:DrawerHost.OpenDrawerCommand}">
            <materialDesign:PackIcon Kind="ArrowAll"/>
        </Button>
    </Grid>
</materialDesign:DrawerHost>
 これを実行すると以下の様になります。
MaterialDesign Drawer
 Drawerを使用するためにはDrawerHostを使用します。
 DrawerHost領域の上下左右にDrawerが表示されます。(大抵の場合はDrawerHostがルート要素になると思います。)
 表示するDrawerはDrawerHostのXxxDrawerContentに定義します。
 例えば、左側Drawerを表示させたい場合はDrawerHost.LeftDrawerContentに表示させたい内容を定義します。
 サンプルコードでは上下左右のDrawerすべてを定義しています。
 
 画面中央のボタンを押すと対応するDrawerが表示されるようになっています。
 Drawerの表示はmaterialDesign:DrawerHost.OpenDrawerCommandを利用します。
 特定のDrawerを表示したい場合はCommandParameterにDock.Xxxを指定します。(Xxxは表示する方向)
 CommandParameterを指定しない場合は定義されているDrawerが全て表示されます。

 Drawerの表示中はDrawer以外の領域はグレー表示され、この部分をクリックするとDrawerが閉じられます。
 ボタンを押す等のアクションでDrawerを閉じたい場合はmaterialDesign:DrawerHost.CloseDrawerCommandを使用します。
 OpenDrawerCommandと同様にCommandParameterで閉じるDrawerを指定します。
 CommandParameterを指定しない場合は表示されている全Drawerを閉じます。

テーマ : プログラミング
ジャンル : コンピュータ

【Material Design Toolkit】 Dialog

 Material Design ToolkitのDialogはウインドウ上にダイアログを表示する機能で、表示する内容も自分で作成することから新しいウインドウを表示する感覚に近いと思います。(ファイル選択ダイアログやMessageBoxとは使い方が異なります)
 ダイアログの制御方法は複数の方法が用意されていますので、状況に合わせて一番使いやすい方法を選択してください。

1.イベントを利用する方法
 最初に説明する方法はDialogHostのイベントを利用する方法です。
 このサンプルではダイアログが閉じられた際にイベントでダイアログの戻り値を取得します。
<UserControl x:Class="DialogDemo.Views.Dialog1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
             xmlns:system="clr-namespace:System;assembly=mscorlib"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">

    <materialDesign:DialogHost DialogClosing="DialogHost_DialogClosing">
        <materialDesign:DialogHost.DialogContent>
            <StackPanel Margin="10">
                <TextBlock Text="Dialog Sample1"/>
                <TextBlock Text="コードビハインド(DialogClosingイベント)を利用したダイアログ"/>
                <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
                    <Button Style="{StaticResource MaterialDesignFlatButton}" Margin="5"
                                Content="OK" Command="{x:Static materialDesign:DialogHost.CloseDialogCommand}">
                        <Button.CommandParameter>
                            <system:Boolean>True</system:Boolean>
                        </Button.CommandParameter>
                    </Button>
                    <Button Style="{StaticResource MaterialDesignFlatButton}" Margin="5"
                                Content="Cancel" Command="{x:Static materialDesign:DialogHost.CloseDialogCommand}">
                        <Button.CommandParameter>
                            <system:Boolean>False</system:Boolean>
                        </Button.CommandParameter>
                    </Button>
                </StackPanel>
            </StackPanel>
        </materialDesign:DialogHost.DialogContent>

        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>

            <TextBlock Grid.Row="0" Grid.Column="0" Text="Dialogの戻り値:"/>
            <TextBlock Grid.Row="0" Grid.Column="1" Name="DialogResultText"/>

            <Button Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"
                Content="Dialog Open"
                Command="{x:Static materialDesign:DialogHost.OpenDialogCommand}"/>
        </Grid>
    </materialDesign:DialogHost>
</UserControl>
using MaterialDesignThemes.Wpf;
using System.Windows.Controls;

namespace DialogDemo.Views
{
    /// <summary>
    /// Dialog1.xaml の相互作用ロジック
    /// </summary>
    public partial class Dialog1 : UserControl
    {
        public Dialog1()
        {
            InitializeComponent();
        }

        private void DialogHost_DialogClosing(object sender, DialogClosingEventArgs eventArgs)
        {
            DialogResultText.Text = eventArgs.Parameter.ToString();
        }
    }
}
 このコードでは以下の様なダイアログが表示されます。
DialogSample1.png
 ダイアログを表示するためには必ずDialogHostが必要になります。
 DialogHostの位置はどこでもよいですが、この領域内にダイアログが表示されるのであまり狭い場所には設定しない方がよさそうです。
 サンプル1ではDialogHostのDialogClosingイベントを利用してダイアログの戻り値を取得しています。
 表示するダイアログの内容はDialogHost.DialogContentに定義します。
 ダイアログの表示はコマンドを使用して行います。
 ダイアログを表示したい場合はmaterialDesign:DialogHost.OpenDialogCommandを使用します。
 また、ダイアログを閉じたい場合はmaterialDesign:DialogHost.CloseDialogCommandを使用します。
 ダイアログを閉じる際にCommandParameterに値を渡して戻り値を返すこともできます。
 このサンプルの場合はOKボタンを押してダイアログを閉じた場合はTrueが、Cancelボタンを押してダイアログを閉じた場合はFalseが返ってきます。
 このサンプルではbool値を返しましたが他の型(文字列等)を返すこともできます。
 この戻り値はDialogClosingイベントのイベント変数を使って受け取ることができます。
 eventArgs.ParameterにCommandParameterの値が入っているのでキャストして使用してください。

2.OpenDialogCommandの引数に表示するダイアログを指定する方法
 2つ目の方法はダイアログの内容をOpenDialogCommandの引数として渡す方法です。
 1つめの方法ではDialogContentの内容が固定されていましたが、この方法では1つのDialogHostで色々な内容のダイアログを表示することができます。
<UserControl x:Class="DialogDemo.Views.Dialog2"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <StackPanel Grid.Row="0">
            <TextBlock Text="Dialog Sample2"/>
            <TextBlock Text=""/>
        </StackPanel>

        <materialDesign:DialogHost Grid.Row="1">
            <StackPanel>
                <Button Command="{x:Static materialDesign:DialogHost.OpenDialogCommand}"
                        Margin="10" Content="ダイアログを表示1">
                    <Button.CommandParameter>
                        <StackPanel Margin="10">
                            <TextBlock Text="OpenDialogCommandのCommandParameterによるダイアログ1"/>
                            <Button Content="閉じる"
                                    Style="{StaticResource MaterialDesignFlatButton}"
                                    Command="{x:Static materialDesign:DialogHost.CloseDialogCommand}"/>
                        </StackPanel>
                    </Button.CommandParameter>
                </Button>

                <Button Command="{x:Static materialDesign:DialogHost.OpenDialogCommand}"
                        Margin="10" Content="ダイアログを表示2">
                    <Button.CommandParameter>
                        <StackPanel Margin="10">
                            <TextBlock Text="OpenDialogCommandのCommandParameterによるダイアログ2"/>
                            <Button Content="閉じる"
                                    Style="{StaticResource MaterialDesignFlatButton}"
                                    Command="{x:Static materialDesign:DialogHost.CloseDialogCommand}"/>
                        </StackPanel>
                    </Button.CommandParameter>
                </Button>
            </StackPanel>
        </materialDesign:DialogHost>
    </Grid>
</UserControl>
 このコードでは以下の様なダイアログが表示されます。
DialogSample2.png
 この方法ではDialogHostのDialogContentには何も指定しません。
 かわりにmaterialDesign:DialogHost.OpenDialogCommandのCommandParameterにダイアログコンテンツを指定します。

 上記のサンプルコードではCommandParameter内に直接ダイアログコンテンツを記載しましたが、UserControl等で作成したダイアログを使用することもできます。
 以下のサンプルコードはダイアログをUserControlで作成しておき、ViewModelをバインディングして呼び出すコードです。
 使用しているSampleDialogとSampleDialogViewModelは「3.ViewModelからダイアログ表示を行う方法」で使用するダイアログを流用しています。
<UserControl x:Class="DialogDemo.Views.Dialog5"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
             xmlns:local="clr-namespace:DialogDemo.Views"
             xmlns:v="clr-namespace:DialogDemo.Views"
             xmlns:vm="clr-namespace:DialogDemo.ViewModels"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <UserControl.DataContext>
        <vm:Dialog5ViewModel/>
    </UserControl.DataContext>
    
    <materialDesign:DialogHost>
        <StackPanel>
            <Button Content="ダイアログ表示" DataContext="{Binding ViewModel}"
                    Command="{x:Static materialDesign:DialogHost.OpenDialogCommand}">
                <Button.CommandParameter>
                    <v:SampleDialog/>
                </Button.CommandParameter>
            </Button>

            <Button Content="ダイアログ表示(バインディング失敗)" 
                    Command="{x:Static materialDesign:DialogHost.OpenDialogCommand}">
                <Button.CommandParameter>
                    <v:SampleDialog DataContext="{Binding ViewModel}"/>
                </Button.CommandParameter>
            </Button>
        </StackPanel>
    </materialDesign:DialogHost>
</UserControl>
using Livet;

namespace DialogDemo.ViewModels
{
    public class Dialog5ViewModel : ViewModel
    {
        public Dialog5ViewModel()
        {
            ViewModel = new SampleDialogViewModel();
        }

        #region ViewModel変更通知プロパティ
        private SampleDialogViewModel _ViewModel;

        public SampleDialogViewModel ViewModel
        {
            get
            { return _ViewModel; }
            set
            {
                if (_ViewModel == value)
                    return;
                _ViewModel = value;
                RaisePropertyChanged();
            }
        }
        #endregion
    }
}
 ダイアログの指定方法はDialog Sample2と同じですが、ViewModelをバインディングする場合は少し注意が必要です。
 CommandParameter以下のSampleDialogのDataContentにViewModelをバインディングしてもうまくいきません。
 SampleDialogにViewModelを渡すためにはButtonのDataContentにViewModelをバインディングします。
 実際にダイアログを表示させてみると以下の様になります。
DialogSample5.png

3.ViewModelからダイアログ表示を行う方法
 3つ目の方法はViewModelからダイアログ表示を行う方法です。
 この方法では表示するダイアログをUserControl等で定義しておく必要があります。
 以下のコードがサンプル3で使用するダイアログとそのViewModelです。
<UserControl x:Class="DialogDemo.Views.SampleDialog"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
             xmlns:system="clr-namespace:System;assembly=mscorlib"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <StackPanel Margin="10">
        <TextBlock Text="Dialog Sample3"/>
        <TextBlock Text="{Binding Time, StringFormat=時刻:{0}}"/>

        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
            <Button Content="OK" Style="{StaticResource MaterialDesignFlatButton}"
                    Command="{x:Static materialDesign:DialogHost.CloseDialogCommand}">
                <Button.CommandParameter>
                    <system:Boolean>True</system:Boolean>
                </Button.CommandParameter>
            </Button>
            <Button Content="Cancel" Style="{StaticResource MaterialDesignFlatButton}"
                Command="{x:Static materialDesign:DialogHost.CloseDialogCommand}">
                <Button.CommandParameter>
                    <system:Boolean>False</system:Boolean>
                </Button.CommandParameter>
            </Button>
        </StackPanel>
    </StackPanel>
</UserControl>
using Livet;
using System;

namespace DialogDemo.ViewModels
{
    public class SampleDialogViewModel : ViewModel
    {
        public SampleDialogViewModel()
        {
            Time = DateTime.Now;
        }

        #region Time変更通知プロパティ
        private DateTime _Time;

        public DateTime Time
        {
            get
            { return _Time; }
            set
            { 
                if (_Time == value)
                    return;
                _Time = value;
                RaisePropertyChanged();
            }
        }
        #endregion

    }
}
 このダイアログはViewModelのTimeプロパティで指定された時刻を表示するだけのダイアログです。
 OKボタンとCancelボタンにはそれぞれ戻り値を設定しています。

<UserControl x:Class="DialogDemo.Views.Dialog3"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
             xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
             xmlns:l="http://schemas.livet-mvvm.net/2011/wpf"
             xmlns:vm="clr-namespace:DialogDemo.ViewModels"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <UserControl.DataContext>
        <vm:Dialog3ViewModel/>
    </UserControl.DataContext>
    
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
               
        <materialDesign:DialogHost Grid.Column="0" Identifier="Dialog1" CloseOnClickAway="True">
            <StackPanel>
                <TextBlock Text="{Binding Result1, StringFormat=ダイアログ1の結果:{0}}"/>
                <Button Content="ダイアログを表示">
                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName="Click">
                            <l:LivetCallMethodAction MethodTarget="{Binding}" MethodName="Open1"/>
                        </i:EventTrigger>
                    </i:Interaction.Triggers>
                </Button>
            </StackPanel>
        </materialDesign:DialogHost>

        <materialDesign:DialogHost Grid.Column="1" Identifier="Dialog2">
            <StackPanel>
                <TextBlock Text="{Binding Result2, StringFormat=ダイアログ2の結果:{0}}"/>
                <Button Content="ダイアログを表示">
                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName="Click">
                            <l:LivetCallMethodAction MethodTarget="{Binding}" MethodName="Open2"/>
                        </i:EventTrigger>
                    </i:Interaction.Triggers>
                </Button>
            </StackPanel>
        </materialDesign:DialogHost>
    </Grid>
</UserControl>
using DialogDemo.Views;
using Livet;
using MaterialDesignThemes.Wpf;

namespace DialogDemo.ViewModels
{
    public class Dialog3ViewModel : ViewModel
    {

        #region Result1変更通知プロパティ
        private bool _Result1;

        public bool Result1
        {
            get
            { return _Result1; }
            set
            { 
                if (_Result1 == value)
                    return;
                _Result1 = value;
                RaisePropertyChanged();
            }
        }
        #endregion

        public async void Open1()
        {
            var dialog = new SampleDialog()
            {
                DataContext = new SampleDialogViewModel()
            };

            // ダイアログ外をクリックして閉じた場合はnullが返ってくる
            var result = await DialogHost.Show(dialog, "Dialog1");
            if(result != null) Result1 = (bool)result;
        }


        #region Result2変更通知プロパティ
        private bool _Result2;

        public bool Result2
        {
            get
            { return _Result2; }
            set
            { 
                if (_Result2 == value)
                    return;
                _Result2 = value;
                RaisePropertyChanged();
            }
        }
        #endregion

        public async void Open2()
        {
            var dialog = new SampleDialog()
            {
                DataContext = new SampleDialogViewModel()
            };

            var result = await DialogHost.Show(dialog, "Dialog2");

            Result2 = (bool)result;
        }

    }
}
 このサンプルのダイアログは以下の様に表示されます。
DialogSample3.png
 このサンプルコードではDialogHostを2つ用意しました。
 DialogHostを複数使用する場合はDialogHostのIdentifierプロパティに名前を付けておきます。
 この名前を使用してダイアログを表示させるDialogHostを指定します。
 名前を付けていないなどで使用するDialogHostが特定できない場合は例外が発生します。
 1つめのDialogHostではCloseOnClickAwayプロパティにTrueを指定しています。
 CloseOnClickAwayがTrueの場合はダイアログ外側の黒背景部分をクリックするとダイアログが閉じます。
 ボタンをクリックした際にViewModelのメソッドでダイアログの表示を行っています。
 Open1メソッド(Open2もほぼ同じ)では表示するダイアログインスタンスを作成します。(必要があればDataContentにViewModelを設定します。)
 DialogHostのShowメソッドに表示したいダイアログインスタンスと使用するDialogHostの名前を指定します。
 Showメソッドは戻り値にダイアログを閉じた際のCommandParameterの値を返します。
 欄外(黒背景)をクリックしてダイアログを閉じた場合は戻り値が存在しないためnullが返ってきます。

4.DialogHostのIsOpenプロパティを使用する方法
 DialoghostのIsOpenプロパティを使用するとコマンドを使用しなくてもダイアログの表示、非表示を制御できます。
 まず、このサンプルで表示するダイアログのコードです。
<UserControl x:Class="DialogDemo.Views.NameDialog"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
             xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
             xmlns:l="http://schemas.livet-mvvm.net/2011/wpf"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <StackPanel Margin="10">
        <TextBlock Text="Dialog Sample4"/>
        <TextBox Text="{Binding Name}" materialDesign:HintAssist.Hint="(名前)"/>

        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
            <Button Content="OK" Style="{StaticResource MaterialDesignFlatButton}">
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="Click">
                        <l:LivetCallMethodAction MethodTarget="{Binding}" MethodName="AcceptDialog"/>
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </Button>
            <Button Content="Cancel" Style="{StaticResource MaterialDesignFlatButton}">
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="Click">
                        <l:LivetCallMethodAction MethodTarget="{Binding}" MethodName="CancelDialog"/>
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </Button>
        </StackPanel>
    </StackPanel>
</UserControl>
 このダイアログは名前入力欄を持つダイアログです。
 OKボタンを押した際にはAcceptDialogメソッドを、Cancelボタンを押した際にはCancelDialogメソッドが呼ばれるようになっています。
 ただ閉じるだけなら共通のメソッドがあればよいのですが、OKボタンとCancelボタンどちらが押されたかを判断するために別々のメソッドを割り当てています。
<UserControl x:Class="DialogDemo.Views.Dialog4"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
             xmlns:l="http://schemas.livet-mvvm.net/2011/wpf"
             xmlns:vm="clr-namespace:DialogDemo.ViewModels"
             xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <UserControl.DataContext>
        <vm:Dialog4ViewModel/>
    </UserControl.DataContext>

    <materialDesign:DialogHost DialogContent="{Binding DialogView}"
                               IsOpen="{Binding IsDialogOpen}">
        <StackPanel>
            <TextBlock Text="Dialog Sample4"/>
            <TextBlock Text="DialogHostのIsOpenによるダイアログ制御"/>
            <TextBlock Text="{Binding Name, StringFormat=名前:{0}}"/>
            <Button Content="ダイアログを表示">
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="Click">
                        <l:LivetCallMethodAction MethodTarget="{Binding}" MethodName="OpenDialog"/>
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </Button>
        </StackPanel>
    </materialDesign:DialogHost>
</UserControl>
using DialogDemo.Views;
using Livet;

namespace DialogDemo.ViewModels
{
    public class Dialog4ViewModel : ViewModel
    {
        public Dialog4ViewModel()
        {
            IsDialogOpen = false;
        }

        #region Name変更通知プロパティ
        private string _Name;

        public string Name
        {
            get
            { return _Name; }
            set
            { 
                if (_Name == value)
                    return;
                _Name = value;
                RaisePropertyChanged();
            }
        }
        #endregion

        #region IsDialogOpen変更通知プロパティ
        private bool _IsDialogOpen;

        public bool IsDialogOpen
        {
            get
            { return _IsDialogOpen; }
            set
            { 
                if (_IsDialogOpen == value)
                    return;
                _IsDialogOpen = value;
                RaisePropertyChanged();
            }
        }
        #endregion


        #region DialogView変更通知プロパティ
        private object _DialogView;

        public object DialogView
        {
            get
            { return _DialogView; }
            set
            { 
                if (_DialogView == value)
                    return;
                _DialogView = value;
                RaisePropertyChanged();
            }
        }
        #endregion

        public void OpenDialog()
        {
            Name = "";
            DialogView = new NameDialog()
            {
                DataContext = this
            };

            IsDialogOpen = true;
        }

        public void AcceptDialog()
        {
            IsDialogOpen = false;
        }

        public void CancelDialog()
        {
            IsDialogOpen = false;
            Name = "";
        }
    }
}
 このコードを実行すると以下の様なダイアログが表示されます。
DialogSample4.png
 ダイアログの表示・非表示をViewModelのIsDialogOpen(DialogHostのIsOpenとバインディング)で制御します。
 ダイアログを表示するのはDialog4、ダイアログを閉じるのはNameDialogの役目です。
 異なるViewでIsDialogOpenプロパティにアクセスする必要があるため、このサンプルではDialog4とNameDialog共通のViewModelを作成しました。(他の方法でもかまいません。とにかく、両方のViewからIsDialogOpenを設定できればOK)
 OpenDialogメソッドでは表示するダイアログインスタンスを作成し(DialogHostのDialogContentにバインディングしてある)、IsDialogOpenをtrueにしています。
 ダイアログを閉じる際にはIsDialogOpenをfalseにするだけです。


 ダイアログを表示する方法を4種類紹介しましたが、個人的には2番目か3番目の方法が使いやすいと思っています。
 
カレンダー
10 | 2023/11 | 12
- - - 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 - -
全記事表示リンク

全ての記事を表示する

カテゴリ
タグリスト

月別アーカイブ
04  10  11  09  08  07  06  05  04  03  02  01  12  11  10  09  08  07  06  04  03  02  01  12  11  10  09  08  07  06  05  04  03  02  01  12  11  10  09 
最新記事
リンク
最新コメント
検索フォーム
Amazon