スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
当サイトは基本をすっ飛ばしてます。基本文法等は、@ITをどうぞ
カテゴリー: スポンサー広告

ボタンに画像を表示する

ボタンに文字ではなく、画像を表示するなんてのは、よくある事であり、やりたい事でもある。
直感的にわかるというのもあるし、場所を取らないというのもある。

Icon置き場的なサイト:
Icon Archive
画像の表示方法:
画像を貼り付けてみようとしたら、勘違いに気づいた。
今回は直下ではなく、Imagesというフォルダを作って、そこに画像を配置した。
※App.xaml
<Application x:Class="TawamureDays.WPFTest.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Window1.xaml">
<Application.Resources>
<BitmapImage x:Key="Button_First_Png" UriSource="Images/Button-First-icon.png"/>
</Application.Resources>
</Application>


※Window1.xaml
<Window x:Class="TawamureDays.WPFTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:tw="http://schemas.tawamureworks.jp/gui"
Title="TawamureDays.WPFTest" Height="300" Width="300"
tw:UIElementBehavior.OnLoadedCommand="{Binding OnLoadedCommand}">
<DockPanel>
<DockPanel.Resources>
</DockPanel.Resources>
<tw:TwContents>
<Image Source="{StaticResource Button_First_Png}"
/>
</tw:TwContents>
</DockPanel>
</Window>

実行するとこんな感じ
20130509_1

この画像をボタンの中身として使う。
<Window x:Class="TawamureDays.WPFTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:tw="http://schemas.tawamureworks.jp/gui"
Title="TawamureDays.WPFTest" Height="300" Width="300"
tw:UIElementBehavior.OnLoadedCommand="{Binding OnLoadedCommand}">
<DockPanel>
<DockPanel.Resources>
</DockPanel.Resources>
<tw:TwContents>
<Button Height="48" Width="52">
<Image Source="{StaticResource Button_First_Png}"
/>
</Button>
</tw:TwContents>
</DockPanel>
</Window>

20130509_2

ボタンの中の画像という感じ。これをボタンの形まで変えようと思うと大変めんどくさい。
StyleのTemplateを弄る必要がある。ここではやらない。
で、このボタンを無効化してみる。
<Window x:Class="TawamureDays.WPFTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:tw="http://schemas.tawamureworks.jp/gui"
Title="TawamureDays.WPFTest" Height="300" Width="300"
tw:UIElementBehavior.OnLoadedCommand="{Binding OnLoadedCommand}">
<DockPanel>
<DockPanel.Resources>
</DockPanel.Resources>
<tw:TwContents>
<Button Height="48" Width="52" IsEnabled="False">
<Image Source="{StaticResource Button_First_Png}"
/>
</Button>
</tw:TwContents>
</DockPanel>
</Window>

20130509_5
同じ画像ではない。見た目が変わらない…。んー。グレースケールの画像を別途用意するのもアレだしなと思い、調べてみたらいいのがあった。
[WPF] How to gray the icon of a MenuItem ?
おお。なんかできそうなので、実装してみよう。ただし、Imageクラスを継承するのではなく、添付プロパティとして実装してみる。
○Helperクラスと添付プロパティ用意
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace TawamureDays.Behaviors {

/// <summary>
/// TawamureDays Imnage用ビヘイビアクラス
/// </summary>
/// <remarks>
/// Image用添付プロパティを提供するクラスです。<br/>
/// </remarks>
public static class ImageBehavior {

#region AutoGrayScaleWhenDisabledプロパティ

/// <summary>
/// 無効化でグレースケール化するかどうかを取得します。
/// </summary>
/// <param name="obj">対象オブジェクト(Image)</param>
/// <returns>true:無効化でグレースケール化する</returns>
public static bool GetAutoGrayScaleWhenDisabled(DependencyObject obj) {
return (bool)obj.GetValue(AutoGrayScaleWhenDisabledProperty);
}

/// <summary>
/// 無効化でグレースケール化するかどうかを設定します。
/// </summary>
/// <param name="obj">対象オブジェクト(Image)</param>
/// <param name="value">true:無効化でグレースケール化する</param>
public static void SetAutoGrayScaleWhenDisabled(DependencyObject obj, bool value) {
obj.SetValue(AutoGrayScaleWhenDisabledProperty, value);
}

/// <summary>無効化でグレースケール化するかどうか</summary>
public static readonly DependencyProperty AutoGrayScaleWhenDisabledProperty =
DependencyProperty.RegisterAttached("AutoGrayScaleWhenDisabled", typeof(bool),
typeof(ImageBehavior),
new UIPropertyMetadata(false,
OnAutoGrayScaleWhenDisabledPropertyChanged));

/// <summary>
/// AutoGrayScaleWhenDisabled用Workerを取得します。
/// </summary>
/// <param name="obj">対象オブジェクト(Image)</param>
/// <returns>AutoGrayScaleWhenDisabled用Worker</returns>
public static AttachedPropertyWorker GetAutoGrayScalePropertyWorker(DependencyObject obj) {
return (AttachedPropertyWorker)obj.GetValue(AutoGrayScalePropertyWorkerProperty);
}

/// <summary>
/// AutoGrayScaleWhenDisabled用Workerを取得します。
/// </summary>
/// <param name="obj">対象オブジェクト(Image)</param>
/// <param name="value">AutoGrayScaleWhenDisabled用Worker</param>
public static void SetAutoGrayScalePropertyWorker(DependencyObject obj, AttachedPropertyWorker value) {
obj.SetValue(AutoGrayScalePropertyWorkerProperty, value);
}

/// <summary>AutoGrayScaleWhenDisabled用Worker</summary>
public static readonly DependencyProperty AutoGrayScalePropertyWorkerProperty =
DependencyProperty.RegisterAttached("AutoGrayScalePropertyWorker",
typeof(AttachedPropertyWorker),
typeof(ImageBehavior),
new UIPropertyMetadata(null));

/// <summary>
/// AutoGrayScaleWhenDisabledプロパティ値変更イベントハンドラ
/// </summary>
/// <param name="dpObj">変更発生元</param>
/// <param name="e">イベントデータ</param>
private static void OnAutoGrayScaleWhenDisabledPropertyChanged(
DependencyObject dpObj, DependencyPropertyChangedEventArgs e) {

var image = dpObj as Image;

if (image == null) {
return;
}

if (Convert.ToBoolean(e.NewValue)) {
AttachedPropertyWorker.SetWorker<AutoGrayScalePropertyWorker>(
image,
ImageBehavior.AutoGrayScalePropertyWorkerProperty);
} else {
image.SetValue(ImageBehavior.AutoGrayScalePropertyWorkerProperty, null);
}

return;
}

#endregion
}
}


○このプロパティ用のWorkerクラスを実装する
/// <summary>
/// TawamureDays Imageコントロールで無効化と共に
/// グレースケールに切り替える為のワーカークラス<br/>
/// </summary>
internal class AutoGrayScalePropertyWorker : AttachedPropertyWorker http://tawamuredays.blog.fc2.com/blog-entry-175.html {

#region コンストラクタ

/// <summary>
/// コンストラクタ
/// </summary>
public AutoGrayScalePropertyWorker() : base() {

}

#endregion

#region AttachedPropertyWorkerメンバー

/// <summary>
/// 初期化処理を行います。
/// </summary>
protected override void OnWorkerSet() {

var image = this.AttachedElement as Image;
image.IsEnabledChanged +=
new DependencyPropertyChangedEventHandler(Image_IsEnabledChanged);

return;
}

/// <summary>
/// 内部リソースを解放します。
/// </summary>
/// <param name="disposing">false:アンマネージリソースのみ解放します。</param>
protected override void OnDispose(bool disposing) {
if (this.IsDisposed) {
return;
}

if (disposing) {
var image = this.AttachedElement as Image;
image.IsEnabledChanged -=
new DependencyPropertyChangedEventHandler(Image_IsEnabledChanged);
}

base.OnDispose(disposing);
return;
}

#endregion

#region イベントハンドラ

/// <summary>
/// Imageオブジェクト IsEnabledプロパティ値変更イベントハンドラ
/// </summary>
/// <param name="sender">イベント発生元</param>
/// <param name="e">イベントデータ</param>
private static void Image_IsEnabledChanged(
object sender, DependencyPropertyChangedEventArgs e) {

var image = sender as Image;

if (image == null || image.Source == null) {
return;
}

if (!image.IsEnabled) {
//無効化されたので、グレースケールに切り替えます。
var bitmapImage = new BitmapImage(new Uri(image.Source.ToString()));

if (bitmapImage.CanFreeze && !bitmapImage.IsFrozen) {
bitmapImage.Freeze();
}

var grayImage = new FormatConvertedBitmap(
bitmapImage,
PixelFormats.Gray32Float,
null, 0);

if (grayImage.CanFreeze && !grayImage.IsFrozen) {
grayImage.Freeze();
}

image.Source = grayImage;

var imageBrush = new ImageBrush(bitmapImage);

if (imageBrush.CanFreeze && !imageBrush.IsFrozen) {
imageBrush.Freeze();
}

image.OpacityMask = imageBrush;

} else if (image.Source is FormatConvertedBitmap) {
image.Source = ((FormatConvertedBitmap)image.Source).Source;
image.OpacityMask = null;
}

return;
}

#endregion
}
ImageやBrush系は、「Freezeできるならやっておく」というのが基本だ。
早速使ってみる。
<Window x:Class="TawamureDays.WPFTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:tw="http://schemas.tawamureworks.jp/gui"
Title="TawamureDays.WPFTest" Height="300" Width="300"
tw:UIElementBehavior.OnLoadedCommand="{Binding OnLoadedCommand}">
<DockPanel>
<DockPanel.Resources>
</DockPanel.Resources>
<tw:TwContents>
<Button Height="48" Width="52" IsEnabled="False">
<Image Source="{StaticResource Button_First_Png}"
tw:ImageBehavior.AutoGrayScaleWhenDisabled="True"
/>
</Button>
</tw:TwContents>
</DockPanel>
</Window>

20130509_6
まさに今押せませんって感じだな。
なお、添付プロパティより先にIsEnabledを設定しても、変化しない。WPFって、宣言した順に処理してるんだな。
スポンサーサイト
当サイトは基本をすっ飛ばしてます。基本文法等は、@ITをどうぞ
カテゴリー: WPF4 | コメント: 0 | トラックバック: 0


この記事へのコメント

コメントの投稿

非公開コメント


サイドバー背後固定表示サンプル

当ブログに書かれたソースコードは流用自由です。

バグ、スペルミス等はありうる事です。

ご利用の際は自己責任でお願いしますm(_ _)m

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。