トップ回答者
Expanderの角の丸さを変えたい

質問
回答
-
WPFでは外見を変更したいときに望むようなプロパティが無ければテンプレートを変更してやると好きなように外見を変更することができます。
たとえば、エクスパンダ―だと「エクスパンダ―のスタイルとテンプレート」にあるようなものです。
テンプレートをエクスパンダ―に適用するには「ControlTemplate の作成による既存のコントロールの外観のカスタマイズ」にあるようなことを理解する必要があります。とはいえ、エクスパンダ―はトリガーやステートも理解していないと1から作るのは大変です。
それは初心者には難しいので、デザイナでにExpanderを配置して、Expanderを右クリックしたメニュー->テンプレートの編集->コピーして編集 とすると、テンプレートを編集しやすいようにリソースを作ってくれます。(VS2012以降からだったかな)
出てきたテンプレートでBorderを探して、CornerRadiusを適用すれば角の丸めができます。それでも難しそうなら以下のコードで
<Window x:Class="WpfApplication1.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"> <Grid> <Expander ExpandDirection="Down" VerticalAlignment="Top" HorizontalAlignment="Stretch" Header="Expander" Loaded="Expander_Loaded" Expanded="Expander_ExpandChanged" Collapsed="Expander_ExpandChanged" Background="LightBlue" > <StackPanel Orientation="Horizontal" Margin="20,0,20,0"> <Button Width="20" Height="20" /> <Button Width="20" Height="20" /> </StackPanel> </Expander> </Grid> </Window>
using System; using System.Windows; using System.Windows.Controls; using System.Windows.Media; namespace WpfApplication1 { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void Expander_Loaded(object sender, RoutedEventArgs e) { var exp = (Expander)sender; Border b = FindChild<Border>(exp, exp); b.CornerRadius = new CornerRadius(0, 0, 0, 0); } private void Expander_ExpandChanged(object sender, RoutedEventArgs e) { //Expanderの最初にあるBorderを見つけて、CornerRadiusを適用する var exp = (Expander)sender; Border b = FindChild<Border>(exp, exp); if (exp.IsExpanded) { switch (exp.ExpandDirection) { case ExpandDirection.Left: b.CornerRadius = new CornerRadius(20, 0, 0, 20); break; case ExpandDirection.Right: b.CornerRadius = new CornerRadius(0, 20, 20, 0); break; case ExpandDirection.Down: b.CornerRadius = new CornerRadius(0, 0, 20, 20); break; case ExpandDirection.Up: b.CornerRadius = new CornerRadius(20, 20, 0, 0); break; } } else { b.CornerRadius = new CornerRadius(0, 0, 0, 0); } } /// <summary> /// 親から子をたどって指定した型で、親のテンプレートによって作られたDependencyObjectを見つける /// </summary> /// <typeparam name="T">見つけたい型</typeparam> /// <param name="d">探索対象</param> /// <param name="templateParent">大本の親</param> /// <returns>見つかったDependencyObject</returns> private static T FindChild<T>(DependencyObject d, DependencyObject templateParent) where T : FrameworkElement { FrameworkElement fe = d as FrameworkElement; if (fe!= null && fe.TemplatedParent != templateParent && d != templateParent) { return null; } T t = d as T; if (t != null) { return t; } int count = VisualTreeHelper.GetChildrenCount(d); for (int i = 0; i < count; i++) { var child = VisualTreeHelper.GetChild(d, i); t = FindChild<T>(child, templateParent); if (t != null) { return t; } } return null; } } }
個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
-
コントロールテンプレートを編集する必要があります。
Visual Studio2015(2013でも)なら、ソリューションエクスプローラーからxamlを右クリック→「Blendでデザイン」でBlendを開き、
オブジェクトウインドウからExpandarを右クリック→「テンプレートの編集」→「コピーして編集」。
Styleが追加されるので、"ExpanderStyle1"のControlTemplate内のBorderのCornerRadiusを好きなように編集すればOkです。
<Style x:Key="ExpanderStyle1" TargetType="{x:Type Expander}"> <!--中略--> <ControlTemplate TargetType="{x:Type Expander}"> <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CornerRadius="3" SnapsToDevicePixels="true">
- 回答としてマーク C.John 2015年8月4日 14:31
すべての返信
-
コントロールテンプレートを編集する必要があります。
Visual Studio2015(2013でも)なら、ソリューションエクスプローラーからxamlを右クリック→「Blendでデザイン」でBlendを開き、
オブジェクトウインドウからExpandarを右クリック→「テンプレートの編集」→「コピーして編集」。
Styleが追加されるので、"ExpanderStyle1"のControlTemplate内のBorderのCornerRadiusを好きなように編集すればOkです。
<Style x:Key="ExpanderStyle1" TargetType="{x:Type Expander}"> <!--中略--> <ControlTemplate TargetType="{x:Type Expander}"> <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CornerRadius="3" SnapsToDevicePixels="true">
- 回答としてマーク C.John 2015年8月4日 14:31
-
WPFでは外見を変更したいときに望むようなプロパティが無ければテンプレートを変更してやると好きなように外見を変更することができます。
たとえば、エクスパンダ―だと「エクスパンダ―のスタイルとテンプレート」にあるようなものです。
テンプレートをエクスパンダ―に適用するには「ControlTemplate の作成による既存のコントロールの外観のカスタマイズ」にあるようなことを理解する必要があります。とはいえ、エクスパンダ―はトリガーやステートも理解していないと1から作るのは大変です。
それは初心者には難しいので、デザイナでにExpanderを配置して、Expanderを右クリックしたメニュー->テンプレートの編集->コピーして編集 とすると、テンプレートを編集しやすいようにリソースを作ってくれます。(VS2012以降からだったかな)
出てきたテンプレートでBorderを探して、CornerRadiusを適用すれば角の丸めができます。それでも難しそうなら以下のコードで
<Window x:Class="WpfApplication1.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"> <Grid> <Expander ExpandDirection="Down" VerticalAlignment="Top" HorizontalAlignment="Stretch" Header="Expander" Loaded="Expander_Loaded" Expanded="Expander_ExpandChanged" Collapsed="Expander_ExpandChanged" Background="LightBlue" > <StackPanel Orientation="Horizontal" Margin="20,0,20,0"> <Button Width="20" Height="20" /> <Button Width="20" Height="20" /> </StackPanel> </Expander> </Grid> </Window>
using System; using System.Windows; using System.Windows.Controls; using System.Windows.Media; namespace WpfApplication1 { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void Expander_Loaded(object sender, RoutedEventArgs e) { var exp = (Expander)sender; Border b = FindChild<Border>(exp, exp); b.CornerRadius = new CornerRadius(0, 0, 0, 0); } private void Expander_ExpandChanged(object sender, RoutedEventArgs e) { //Expanderの最初にあるBorderを見つけて、CornerRadiusを適用する var exp = (Expander)sender; Border b = FindChild<Border>(exp, exp); if (exp.IsExpanded) { switch (exp.ExpandDirection) { case ExpandDirection.Left: b.CornerRadius = new CornerRadius(20, 0, 0, 20); break; case ExpandDirection.Right: b.CornerRadius = new CornerRadius(0, 20, 20, 0); break; case ExpandDirection.Down: b.CornerRadius = new CornerRadius(0, 0, 20, 20); break; case ExpandDirection.Up: b.CornerRadius = new CornerRadius(20, 20, 0, 0); break; } } else { b.CornerRadius = new CornerRadius(0, 0, 0, 0); } } /// <summary> /// 親から子をたどって指定した型で、親のテンプレートによって作られたDependencyObjectを見つける /// </summary> /// <typeparam name="T">見つけたい型</typeparam> /// <param name="d">探索対象</param> /// <param name="templateParent">大本の親</param> /// <returns>見つかったDependencyObject</returns> private static T FindChild<T>(DependencyObject d, DependencyObject templateParent) where T : FrameworkElement { FrameworkElement fe = d as FrameworkElement; if (fe!= null && fe.TemplatedParent != templateParent && d != templateParent) { return null; } T t = d as T; if (t != null) { return t; } int count = VisualTreeHelper.GetChildrenCount(d); for (int i = 0; i < count; i++) { var child = VisualTreeHelper.GetChild(d, i); t = FindChild<T>(child, templateParent); if (t != null) { return t; } } return null; } } }
個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
-
WPFでは外見を変更したいときに望むようなプロパティが無ければテンプレートを変更してやると好きなように外見を変更することができます。
たとえば、エクスパンダ―だと「エクスパンダ―のスタイルとテンプレート」にあるようなものです。
テンプレートをエクスパンダ―に適用するには「ControlTemplate の作成による既存のコントロールの外観のカスタマイズ」にあるようなことを理解する必要があります。教えていただいたリンクを読んでみましたが、理解度30%くらいだったので、また理解が進んでからもう一度見たいと思います。
デザイナでにExpanderを配置して、Expanderを右クリックしたメニュー->テンプレートの編集->コピーして編集
このやり方で実現できました。
ありがとうございます。