質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

XAML

XAML(Extensible Application Markup Language)はWPF、Silverlight、Windows PhoneそしてWindows Store appsでユーザーインターフェースを定義するために使われるXML言語です。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

2回答

3381閲覧

マウスホバー時のプロパティトリガーの動作について

bep

総合スコア6

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

XAML

XAML(Extensible Application Markup Language)はWPF、Silverlight、Windows PhoneそしてWindows Store appsでユーザーインターフェースを定義するために使われるXML言語です。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

0グッド

1クリップ

投稿2019/10/30 02:19

編集2019/10/30 07:21

マウスホバー時のプロパティトリガーの動作について教えて下さい。

まず以下のの通りXAMLでLabelのStyleを定義します。

XAML

1<Window.Resources> 2 <Style TargetType="{x:Type Label}"> 3 <Style.Triggers> 4 <Trigger Property="IsMouseOver" Value="True"> 5 <Setter Property="FontSize" Value="30"/> 6 <Setter Property="Foreground" Value="Red"/> 7 <Setter Property="Background" Value="Yellow"/> 8 </Trigger> 9 </Style.Triggers> 10 </Style> 11 </Window.Resources> 12 <Grid> 13 <Label x:Name="MyLabel" Content="Mouse hover over a Label" 14 HorizontalAlignment="Center" 15 VerticalAlignment="Center"/> 16 </Grid>

このコードの場合はマウスホバー時にFontSize、Foreground、Background全て
正しく変化します。

しかし諸々の理由でコードビハインドからBackgroundプロパティの色をYellow以外に
変える必要があります。例えば上記のXAMLに対して以下の通りコンストラクター
の中でBackgroundプロパティをWhiteに設定します。

C#

1public MainWindow() 2{ 3 InitializeComponent(); 4 MyLabel.Background = Brushes.White; 5}

このようにするとマウスホバー時のBackgroundがWhiteになってしまいます。
望む動作はStyleで定義した通りのYellowになって欲しいのですが方法がわかりません。

何か良い方法がありましたらご教示ください。

実際に実現したいことはLabelコントロールではなくCalendarコントロールです。
改めてXAMLの抜粋を記載致します。複雑になるため動作に関係のないイベントハンドラ
は省略しております。

XAML

1<Viewbox> 2<Calendar x:Name="MyCalendar"> 3 <Calendar.CalendarDayButtonStyle> 4 <Style TargetType="{x:Type CalendarDayButton}"> 5 <Setter Property="Template"> 6 <Setter.Value> 7 <ControlTemplate TargetType="{x:Type CalendarDayButton}"> 8 <Border x:Name="MyHoverButtonBorder" BorderThickness="0.1"> 9 <ContentPresenter/> 10 </Border> 11 <ControlTemplate.Triggers> 12 <!-- マウスオーバー --> 13 <Trigger Property="IsMouseOver" Value="True"> 14 <Setter TargetName="MyHoverButtonBorder" Property="BorderBrush" Value="Pink" /> 15 <Setter TargetName="MyHoverButtonBorder" Property="Background" Value="Pink" /> 16 <Setter Property="Foreground" Value="White" /> 17 </Trigger> 18 </ControlTemplate.Triggers> 19 </ControlTemplate> 20 </Setter.Value> 21 </Setter> 22 </Style> 23 </Calendar.CalendarDayButtonStyle> 24</Calendar> 25</Viewbox>

日をクリックすると背景をグリーン色にしているのですが、事情により
月が変わるたびに全ての日の背景を一度ホワイト色でクリアする必要があります。
クリアはコードビハインドで行っていますが、そうするとマウスホバー時に上記の
XAMLで指定したピンク色にはならずホワイト色のままになってしまいます。
ホワイト色でクリアした後でも個々の日をマウスホバー時にピンク色にすることは
可能でしょうか?

上手く動作したCalendarDayButtonの背景をクリアするコードは以下の通りです。

C#

1void AllDaysClear(CalendarDayButton[] days) 2{ 3 foreach (var day in days) 4 { 5 var border = day.Children<Border>().FirstOrDefault(); 6 if (border != null) 7 { 8 border.BorderBrush = Brushes.Black; 9 //border.Background = Brushes.White; //期待通りの動作をしない 10 border.ClearValue(BackgroundProperty); //期待通りの動作をする 11 day.IsEnabled = true; 12 } 13 } 14}

Childrenメソッドは「じんぐる様」の下記サイトのコードを拝借し検証しました。
https://blog.xin9le.net/entry/2013/10/29/222336

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2019/10/30 04:32

ControlTemplate は私の回答に書いたものです。解決法は知っていますが、無視された上でこのような扱いをされたのでは回答する気がなくなります。
bep

2019/10/30 04:52

大変失礼しました。 ご回答頂きましたお二人への回答を書くのに時間がかかってしまいすみませんでした。
guest

回答2

0

Style.TriggersとControlTemplate.Triggersの違い - プログラマーな日々

ControlTemplate.Triggers を使ってみてください。

C#

1<Window x:Class="WpfApp1.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 xmlns:local="clr-namespace:WpfApp1" 7 mc:Ignorable="d" 8 Title="MainWindow" Height="450" Width="800"> 9 <Window.Resources> 10 <ControlTemplate TargetType="{x:Type Label}" x:Key="labelTemplate"> 11 <Border Background="{TemplateBinding Background}" x:Name="border"> 12 <ContentPresenter/> 13 </Border> 14 <ControlTemplate.Triggers> 15 <Trigger Property="IsMouseOver" Value="True"> 16 <Setter Property="FontSize" Value="30"/> 17 <Setter Property="Foreground" Value="Red"/> 18 <Setter TargetName="border" Property="Background" Value="Yellow"/> 19 </Trigger> 20 </ControlTemplate.Triggers> 21 </ControlTemplate> 22 </Window.Resources> 23 <Grid> 24 <Label x:Name="MyLabel" Content="Mouse hover over a Label" 25 Template="{StaticResource labelTemplate}" 26 HorizontalAlignment="Center" 27 VerticalAlignment="Center"> 28 </Label> 29 </Grid> 30</Window>

投稿2019/10/30 02:43

編集2019/10/30 03:33
Zuishin

総合スコア28660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

bep

2019/10/30 04:47

ご回答ありがとうございます。 リンク先のサイトを確認しました。ControlTemplate.Triggersを使用する必要があるのですね。 質問内容を編集致しました。 実は実際のプログラムはCalendarコントロールを使用しており、個々の日を表すCalendarDayButton コントロールの背景に対して、最初に提示しましたLabelの例と同様の動作をさせたいと考えております。 ControlTemplate.Triggersを使用しているのですが、期待通りには動作しておりません。 教えて頂きましたXAMLと比べますと、違いはTemplateプロパティを使用していることかと思いますが これが原因でしょうか?あるいは不足している設定があるのでしょうか?
Zuishin

2019/10/30 04:50

あとは単なる間違い探しでしょう。 <Border x:Name="MyHoverButtonBorder" BorderThickness="0.1"> <Border Background="{TemplateBinding Background}" x:Name="border">
bep

2019/10/30 05:26

ご回答ありがとうございます。 Background="{TemplateBinding Background}"を追記してみたのですが 背景色はホワイト色のままでした。コードビハインドに問題があるかもしれ ませんので、そちらを再検討してみます。
Zuishin

2019/10/30 05:32 編集

バインド先が違うだけのこと。takabosoft さんの方法でもできるので、そっちを採用して質問のコードを書き直してください。
bep

2019/10/30 07:05

お返事ありがとうございます。 takabosoft さんから頂きました以下の方法でBorderコントロールのBackgroundプロパティを クリアしたところ上手くいきました。 MyLabel.ClearValue(BackgroundProperty); コードビハインドを追記しておきます。 どうもありがとうございました。
guest

0

ベストアンサー

依存関係プロパティ値の優先順位
https://docs.microsoft.com/ja-jp/dotnet/framework/wpf/advanced/dependency-property-value-precedence

をみた感じでは、

ローカル プロパティ セットは最高の優先順位で設定されます

とありますので、他のトリガーなどでは優先順位が低く、適用されないんだろうなと思います。

どういう解決策があるのかはわかりませんが、

例えばラベルの背景を変えるのではなくて、

  • ラベルの装飾として置いたボーダーの背景色
  • ラベルとレイヤーを組んだ別のコントロールの背景色

をコードビハインドで変えるという手が使えるのかなと思いました。

ただ、これだけだと実行時、マウスオーバーで四角の上に別の四角を描画するという形になり、描画範囲に誤差が出るとゴミが表示される気がするのでUseLayoutRounding="True"を入れてごまかしてあります。

xaml

1<Window x:Class="WpfApplication1.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 xmlns:local="clr-namespace:WpfApplication1" 7 mc:Ignorable="d" 8 Title="MainWindow" Height="350" Width="525" 9 UseLayoutRounding="True"> 10 11 <Window.Resources> 12 <Style TargetType="{x:Type Label}"> 13 <Style.Triggers> 14 <Trigger Property="IsMouseOver" Value="True"> 15 <Setter Property="FontSize" Value="30"/> 16 <Setter Property="Foreground" Value="Red"/> 17 <Setter Property="Background" Value="Yellow"/> 18 </Trigger> 19 </Style.Triggers> 20 </Style> 21 </Window.Resources> 22 23 <Grid> 24 <Border x:Name="MyLabelBorder" 25 HorizontalAlignment="Center" 26 VerticalAlignment="Center"> 27 <Label x:Name="MyLabel" Content="Mouse hover over a Label" /> 28 </Border> 29 </Grid> 30</Window>

csharp

1namespace WpfApplication1 2{ 3 /// <summary> 4 /// MainWindow.xaml の相互作用ロジック 5 /// </summary> 6 public partial class MainWindow : Window 7 { 8 public MainWindow() 9 { 10 InitializeComponent(); 11 MyLabelBorder.Background = Brushes.Red; 12 } 13 } 14}

イメージ説明

※自分はあんまりWPFは詳しくないので、もうちょっと上手い方法がありそうです。


日をクリックすると背景をグリーン色にしているのですが、事情により

月が変わるたびに全ての日の背景を一度ホワイト色でクリアする必要があります。
クリアはコードビハインドで行っていますが、そうするとマウスホバー時に上記の
XAMLで指定したピンク色にはならずホワイト色のままになってしまいます。
ホワイト色でクリアした後でも個々の日をマウスホバー時にピンク色にすることは
可能でしょうか?

えーと

日をクリックすると背景をグリーン色にしている

もコードビハインドで、

全ての日の背景を一度ホワイト色でクリアする

もコードビハインドでBrushes.Whiteか何かを何かに代入しているのかなと思いますが、
クリアをBrushes.Whiteではなくnullを代入してみるとどうでしょう?


更に追記:
最初のラベルのサンプルで試していましたが

MyLabel.Background = Brushes.Red;

としたあと、

MyLabel.ClearValue(BackgroundProperty);

とすれば、添付プロパティの内容をクリアできるようです。
nullではなく、こちらを使ってみてください。

投稿2019/10/30 02:41

編集2019/10/30 06:48
takabosoft

総合スコア8356

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

bep

2019/10/30 04:02

ご回答ありがとうございます。 優先順位については考慮してませんでした。 教えて頂いた通り、追加したBorderのBackgroundを変えることにより 提示させて頂いたサンプルプログラムでは期待通りの動作を得られました。 実は実際のプログラムではCalendarコントロールの個々の日を表す CalendarDayButtonの背景について同様の動作をさせたいと考えて います(日をクリックしたとき背景色を変えたい)。 今のところコードから設定した色が勝ってしまいスタイルで定義した マウスホバー時の色は適用されませんでした。後ほど、改めてXAMLを 提示させていただきます。 本件につきましてはとても勉強になりました。
Zuishin

2019/10/30 04:38 編集

何を勉強したのか知りませんが、質問のコードはこの回答ではなく私の回答を参考にしたものです。ここからの回答は、私の回答との違いを答える間違い探しでしかありません。
bep

2019/10/30 04:56

事情が理解できておりませんでした。 改めてご回答ありがとうございました。
takabosoft

2019/10/30 04:58

null代入案の回答を追記しました。
bep

2019/10/30 05:47

ご回答ありがとうございます。 はい。特定の日をクリックするとき(グリーン)も全ての日をクリアするとき(ホワイト)も コードビハインドで行っております。クリアする箇所ではBorderコントロールのBackground プロパティにBrushes.Whiteを代入しています。 これをnullに替えてみたのですが、動作は変わりませんでした。
Zuishin

2019/10/30 05:55

質問のコードを takabosoft さんの最初の案を採用して作ったコードに差し替えてください。
Zuishin

2019/10/30 05:57

> 今のところコードから設定した色が勝ってしまいスタイルで定義した マウスホバー時の色は適用されませんでした。 のコードです。
takabosoft

2019/10/30 06:42

あ、nullじゃだめでした、すみません。
takabosoft

2019/10/30 06:49

ClearValue案を追記しました(^_^;何度もすみません。
bep

2019/10/30 07:06

お返事ありがとうございます。 コードビハインド内で以下の方法を実行したところ期待通り背景色 が変わりました。 MyLabel.ClearValue(BackgroundProperty); どうもありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問