質問するログイン新規登録
C#

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

XAML

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

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

WPF

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

Q&A

解決済

1回答

2691閲覧

ControlTemplate内のコントロールをコードビハインドで取得しプロパティを書き換えると、Triggerが動作しなくなる。

anonymousss

総合スコア13

C#

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

XAML

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

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

WPF

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

0グッド

0クリップ

投稿2020/10/26 09:41

編集2020/10/27 11:30

0

0

自作のExpanderコントロールの動作について。

ControlTemplateにToggleButtonを3つもっておりそれぞれのCheck状態に応じてClose, Small open, Large openの3つのStateを持っています。
StateをAppSettingsに保存し、次回アプリケーションを起動した際にExpanderの状態を復元したいと思い、以下のような復元処理を作成しました。

c#

1View_Loaded(object sender, RoutedEventArgs e) 2{ 3 var tb2 = this.Expander.Template.FindName("togglebutton2", this.Expander) as ToggleButton; 4 5 // Restore expander state 6 switch (AppSettings.Current.ExpanderOpenState) 7 { 8 default: 9 case 0: // Close 10 break; 11 case 1: // Small 12 this.Expander.IsExpanded = true; 13 break; 14 case 2: // Large 15 this.Expander.IsExpanded = true; 16 tb2.IsChecked = true; 17 break; 18 } 19}

復元自体は問題なく行えたのですが、もともと動きの正しかったExpanderの動作が上記復元処理を入れてからおかしくなりました。
具体的には、
・Small復元時
問題なし
・Large復元時
Triggerで制御しているはずの(togglebutton2の)IsCheckedtrueのまま外れなくなる。

ControlTemplate内のコントロール取得の仕方が悪いのか、別の問題があるのか、なにかわかることがあればご教授よろしくお願い致します。

イメージ説明

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

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

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

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

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

TN8001

2020/10/26 12:44

やりたいことは明確にわかります。 >ToggleButtonを3つもっており 通常のExpanderはToggleButton1つでExpanded・Collapsedです。 3Stateになったとしても2つでは?(Expanderの中にExpanderを入れたような状態と考えています) どのようなUIを考えているかにもよりますが、ToggleButton.IsThreeState=Trueを使ってもいいかもしれません。 >Triggerで制御しているはずの(togglebutton2の)IsCheckedがtrueのまま外れなくなる。 Style.Triggerでもそうですが、本体?に直接設定されたプロパティはそちらが優先されて変更されません。 恐らくそういう状態になっていると思います。 やっている例がありそうですが見つけられませんでした(汎用的に作るとなると相当面倒なせいかもしれません。素の状態でも4方向ありますし) 汎用性を考えなければそこまで難しくない気はしますが、入れ子Expander等でお茶を濁してもいい気もします^^;
anonymousss

2020/10/26 13:17

>>Triggerで制御しているはずの(togglebutton2の)IsCheckedがtrueのまま外れなくなる。 >Style.Triggerでもそうですが、本体?に直接設定されたプロパティはそちらが優先されて変更されません。 >恐らくそういう状態になっていると思います。 その様な仕様?があったのですね。 それがわかっただけでもありがたいです。 既存のコントロールで対応しようとすると復元が必要なExpandeを使用している箇所のみ、IsChecked,UnChecked EventHanderでTriggerで行っている処理を行う必要がありそうですね。 Expanderのコントロール自体は私が作成したものではないのであまり大きく作り直すのが難しいので上記の対応でしのごうかと思います^^;
TN8001

2020/10/26 14:23

>既存のコントロールで対応しようとすると復元が必要なExpandeを使用している箇所のみ、IsChecked,UnChecked EventHanderでTriggerで行っている処理を行う必要がありそうですね。 やりようはいろいろあると思うのですが、この情報だけでは何とも言えません^^; >Expanderのコントロール自体は私が作成したものではないので なるほど。なので詳細のコード・xamlは出せない感じでしょうか。 ある程度拡張を考えて作られたカスタムコントロールなら、なにかDependencyPropertyが用意してあるかもしれません(ExpanderのToggleButton.IsCheckedがIsExpandedにバインドしてるように) https://github.com/dotnet/wpf/blob/538c195e0bda908acafb1d1addd068530ffcb6c8/src/Microsoft.DotNet.Wpf/src/Themes/XAML/Expander.xaml#L503 3Stateが画像か図でどんな見た目かわかれば、雑に作って試してみてもいいのですが。。
anonymousss

2020/10/27 11:32

すみません。遅くなりましたが、コントロールのイメージ図を作成してみました。 サイドナビゲーションバーのようなイメージです。
guest

回答1

0

ベストアンサー

まずタイトルの件は、そういう仕様ということになります。
Dependency Property Value Precedence - WPF .NET Framework | Microsoft Docs


追記いただいた図から再現しようとしたんですが、ToggleButton3はトグルしておらずどういう処理なのかわかりませんでした。

仕方がないのでトグルボタン2個パターンで同じ動きの組、都合4つ使って図に合わせてみました(2個でもできますが、位置の移動等が煩雑になるので^^;
雑に作ってみたところ、TriggerIsCheckedを変えるような状況にならず、問題を再現できませんでした(xamlがないとこれ以上検討できそうにないです^^;

このままでは使い物にならないでしょうが、何かのヒントになれば幸いです。

xml

1<Window 2 x:Class="Questions300473.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 Width="450" 6 Height="450" 7 Closing="Window_Closing" 8 Loaded="Window_Loaded"> 9 <Window.Resources> 10 11 <Style x:Key="ExpanderStyle1" TargetType="{x:Type Expander}"> 12 <Setter Property="ClipToBounds" Value="True" /> 13 <Setter Property="Template"> 14 <Setter.Value> 15 <ControlTemplate TargetType="{x:Type Expander}"> 16 <Border> 17 <DockPanel> 18 <Grid x:Name="HeaderSite" DockPanel.Dock="Top"> 19 <ToggleButton 20 x:Name="Close2Small" 21 HorizontalAlignment="Right" 22 VerticalAlignment="Top" 23 Content="&lt;" 24 IsChecked="{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" 25 ToolTip="Close→Small" /> 26 <ToggleButton 27 x:Name="Small2Close" 28 HorizontalAlignment="Left" 29 Content="&gt;" 30 IsChecked="{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" 31 ToolTip="Small→Close" 32 Visibility="Hidden" /> 33 34 <ToggleButton 35 x:Name="Small2Large" 36 HorizontalAlignment="Right" 37 Content="&lt;" 38 ToolTip="Small→Large" 39 Visibility="Hidden" /> 40 <ToggleButton 41 x:Name="Large2Small" 42 HorizontalAlignment="Left" 43 Content="&gt;" 44 IsChecked="{Binding IsChecked, Mode=TwoWay, ElementName=Small2Large}" 45 ToolTip="Large→Small" 46 Visibility="Hidden" /> 47 </Grid> 48 49 <ContentPresenter 50 x:Name="ExpandSite" 51 Margin="0,0,-200,0" 52 DockPanel.Dock="Bottom" 53 Focusable="false" 54 Visibility="Collapsed" /> 55 </DockPanel> 56 </Border> 57 <ControlTemplate.Triggers> 58 <!-- Close->Small --> 59 <Trigger SourceName="Close2Small" Property="IsChecked" Value="True"> 60 <Setter TargetName="Close2Small" Property="IsEnabled" Value="False" /> 61 <Setter TargetName="Small2Close" Property="Visibility" Value="Visible" /> 62 <Setter TargetName="Small2Large" Property="Visibility" Value="Visible" /> 63 </Trigger> 64 65 <!-- Small->Large --> 66 <Trigger SourceName="Small2Large" Property="IsChecked" Value="True"> 67 <Setter TargetName="ExpandSite" Property="Margin" Value="0" /> 68 <Setter TargetName="Small2Large" Property="Visibility" Value="Hidden" /> 69 <Setter TargetName="Large2Small" Property="Visibility" Value="Visible" /> 70 </Trigger> 71 72 <Trigger Property="IsExpanded" Value="True"> 73 <Setter TargetName="ExpandSite" Property="Visibility" Value="Visible" /> 74 </Trigger> 75 </ControlTemplate.Triggers> 76 </ControlTemplate> 77 </Setter.Value> 78 </Setter> 79 </Style> 80 </Window.Resources> 81 <Grid> 82 <Expander 83 x:Name="Expander" 84 Margin="20" 85 HorizontalAlignment="Right" 86 Style="{DynamicResource ExpanderStyle1}"> 87 <Rectangle 88 Width="400" 89 Height="300" 90 Fill="Red" /> 91 </Expander> 92 93 94 <!-- 依存関係プロパティ値の優先順位 --> 95 <CheckBox 96 x:Name="checkBox" 97 HorizontalAlignment="Left" 98 VerticalAlignment="Top" 99 Content="Triggerのテスト"> 100 <CheckBox.Style> 101 <Style TargetType="{x:Type CheckBox}"> 102 <Style.Triggers> 103 <Trigger Property="IsMouseOver" Value="True"> 104 <Setter Property="IsChecked" Value="True" /> 105 </Trigger> 106 <!-- ↓は無くても同じだがあったとしてもダメ --> 107 <!--<Trigger Property="IsMouseOver" Value="False"> 108 <Setter Property="IsChecked" Value="False" /> 109 </Trigger>--> 110 </Style.Triggers> 111 </Style> 112 </CheckBox.Style> 113 </CheckBox> 114 </Grid> 115</Window>

cs

1using System.ComponentModel; 2using System.Windows; 3using System.Windows.Controls.Primitives; 4 5namespace Questions300473 6{ 7 public enum ThreeState { Close, Small, Large, } 8 9 public partial class MainWindow : Window 10 { 11 public MainWindow() => InitializeComponent(); 12 13 private void Window_Loaded(object sender, RoutedEventArgs e) 14 { 15 var Small2Large = Expander.Template.FindName("Small2Large", Expander) as ToggleButton; 16 17 switch(Properties.Settings.Default.ExpanderOpenState) 18 { 19 default: 20 case ThreeState.Close: 21 break; 22 case ThreeState.Small: 23 Expander.IsExpanded = true; 24 break; 25 case ThreeState.Large: 26 Expander.IsExpanded = true; 27 Small2Large.IsChecked = true; 28 break; 29 } 30 31 32 // 依存関係プロパティ値の優先順位 Triggerのテスト 33 // あまりに露骨なので「そりゃそうだ」という気もしますが、 34 // ↓を実行するとMouseOverに反応しなくなります。 35 //checkBox.IsChecked = true; 36 } 37 38 private void Window_Closing(object sender, CancelEventArgs e) 39 { 40 var Small2Large = Expander.Template.FindName("Small2Large", Expander) as ToggleButton; 41 var state = !Expander.IsExpanded ? ThreeState.Close 42 : Small2Large.IsChecked == false ? ThreeState.Small 43 : ThreeState.Large; 44 45 Properties.Settings.Default.ExpanderOpenState = state; 46 Properties.Settings.Default.Save(); 47 } 48 } 49}

投稿2020/10/28 09:14

編集2023/07/23 08:55
TN8001

総合スコア10124

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.30%

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

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

質問する

関連した質問