遅い→起動時

http://d.hatena.ne.jp/pmint/

WPFでWindowsXPでも使える影付きウィンドウを作ってみた (0)


できあがり。


Cream Pixels Made by Mizanur Rahman. (CC BY-SA 3.0)

### WPFで影付きウィンドウ作成

  1. Window.WindowStyle = None
  2. Window.AllowsTransparency = True
  3. Window.BorderThickness を適当に太くする。
    ここに影を描画するとウィンドウ背景とは別に影を付けられる。
  4. Window.EffectDropShadowEffect を与える。
    影のぼかし具合もこのクラスで設定。
  5. 最大化時には影部分まで画面に入るので、影を消す必要がある。(WindowState復帰時に再び影付きに)
    最大化時にだけ Window.BorderThicknessThickness(0)にすればいい。

Windowsに認識させるRegionの設定は要らない。影部分(DropShadowEffect)の不透明度(Opacity)に応じてWindowsがクリックにヒットするかどうか決めてくれる。自動。*1


(デザイン時の様子)

プロジェクトファイル(VS2010)

DropShadow2.zip

ClickOnceで実行してみる
IE以外の人は警告を受けながらsetup.exeを実行してね)

コード(C#)

MainWindow.xaml

XAML
WindowStyle、AllowsTransparency、BorderThicknessが大事。

<Window x:Class="DropShadow2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525" MouseDown="Window_MouseDown"
        WindowStyle="None" AllowsTransparency="True" WindowStartupLocation="CenterScreen" BorderThickness="30" ResizeMode="CanResizeWithGrip" 
        Activated="Window_Activated" Deactivated="Window_Deactivated" StateChanged="Window_StateChanged"
        >
    <Window.Background>
        <ImageBrush ImageSource="/DropShadow2;component/Images/cream_pixels.png" Stretch="None" TileMode="Tile" Viewport="0,0,160,160" ViewportUnits="Absolute" />
    </Window.Background>
</Window>
MainWindow.xaml.cs

分離コードや相互作用ロジックなどと呼ばれるC#コード。
なんてことはないコード。

using System;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Effects;

namespace DropShadow2
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        private DropShadowEffect _effect = new DropShadowEffect();

        public MainWindow()
        {
            InitializeComponent();

            {
                _effect.Color = Colors.Black;
                _effect.BlurRadius = 20;
                _effect.ShadowDepth = 0;
                _effect.Opacity = 0.25;
                _effect.RenderingBias = RenderingBias.Performance;
            }
        }

        private void Window_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
                this.DragMove();
        }

        private void Window_Activated(object sender, EventArgs e)
        {
            this.Effect = _effect;
        }

        private void Window_Deactivated(object sender, EventArgs e)
        {
            this.Effect = null;
        }

        private void Window_StateChanged(object sender, EventArgs e)
        {
            var c = (Window)sender;
            this.BorderThickness = (c.WindowState == WindowState.Maximized) ? new Thickness(0) : new Thickness(30);
        }
    }
}

*1:本当に透明な部分じゃないとクリック透過にならないけどね