私は xaml クラスを構築しましたが、それを抽象基本クラスとして使用したい場合は、xaml なしで構築する必要があることに気付きました。しかし、xaml から C# への変換が完了したとき、結果は同じではありませんでした。
例: 前景が同じではありません。(左がViewDialogX、右がViewDialogC)
ViewDialogX.xaml
<ContentControl x:Class="xmlns.ViewDialogX"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:my="clr-namespace:xmlns"
HorizontalAlignment="Center" VerticalAlignment="Center">
<ContentControl.Template>
<ControlTemplate TargetType="my:ViewDialogX">
<Border MinWidth="160" MinHeight="90" Margin="1,2,3,3" Padding="4">
<Border.Effect>
<DropShadowEffect BlurRadius="10" Opacity="3" ShadowDepth="0" />
</Border.Effect>
<GroupBox Header="{TemplateBinding Title}" Background="{DynamicResource ControlBackgroundBrush}">
<Grid Width="{TemplateBinding ContentWidth}" Height="{TemplateBinding ContentHeight}">
<ContentPresenter Margin="{TemplateBinding Padding}" Content="{TemplateBinding Content}" />
</Grid>
</GroupBox>
</Border>
</ControlTemplate>
</ContentControl.Template>
</ContentControl>
ViewDialogX.xaml.cs
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Media.Effects;
using System.Windows.Markup;
namespace xmlns
{
public partial class ViewDialogX : ContentControl
{
public ViewDialogX()
{
InitializeComponent();
}
public static readonly DependencyProperty TitleProperty =
DependencyProperty.RegisterAttached("Title", typeof(string), typeof(ViewDialogX), new PropertyMetadata(" "));
public string Title { get { return (string)this.GetValue(TitleProperty); } set { this.SetValue(TitleProperty, value); } }
public static readonly DependencyProperty ContentWidthProperty =
DependencyProperty.RegisterAttached("ContentWidth", typeof(double), typeof(ViewDialogX), new PropertyMetadata(double.NaN));
public double ContentWidth { get { return (double)this.GetValue(ContentWidthProperty); } set { this.SetValue(ContentWidthProperty, value); } }
public static readonly DependencyProperty ContentHeightProperty =
DependencyProperty.RegisterAttached("ContentHeight", typeof(double), typeof(ViewDialogX), new PropertyMetadata(double.NaN));
public double ContentHeight { get { return (double)this.GetValue(ContentHeightProperty); } set { this.SetValue(ContentHeightProperty, value); } }
public virtual void OnClosing(CancelEventArgs e) { }
public virtual void Close() { }
}
}
ViewDialogC.cs
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Media.Effects;
using System.Windows.Markup;
namespace xmlns
{
public class ViewDialogC : ContentControl
{
public ViewDialogC()
{
if (!DesignerProperties.GetIsInDesignMode(this))
{
this.SetValue(ViewDialogC.HorizontalAlignmentProperty, HorizontalAlignment.Center);
this.SetValue(ViewDialogC.VerticalAlignmentProperty, VerticalAlignment.Center);
FrameworkElementFactory border = new FrameworkElementFactory(typeof(Border));
border.SetValue(Border.MinWidthProperty, 160d);
border.SetValue(Border.MinHeightProperty, 90d);
border.SetValue(Border.MarginProperty, new Thickness(1, 2, 3, 3));
border.SetValue(Border.PaddingProperty, new Thickness(4));
border.SetValue(Border.EffectProperty, new DropShadowEffect() { BlurRadius = 10, Opacity = 3, ShadowDepth = 0 });
FrameworkElementFactory group = new FrameworkElementFactory(typeof(GroupBox));
group.SetValue(GroupBox.HeaderProperty, new TemplateBindingExtension(ViewDialogC.TitleProperty));
group.SetResourceReference(GroupBox.BackgroundProperty, "ControlBackgroundBrush");
FrameworkElementFactory grid = new FrameworkElementFactory(typeof(Grid));
grid.SetValue(Grid.WidthProperty, new TemplateBindingExtension(ViewDialogC.ContentWidthProperty));
grid.SetValue(Grid.HeightProperty, new TemplateBindingExtension(ViewDialogC.ContentHeightProperty));
FrameworkElementFactory content = new FrameworkElementFactory(typeof(ContentPresenter));
content.SetValue(ContentPresenter.MarginProperty, new TemplateBindingExtension(ViewDialogC.PaddingProperty));
content.SetValue(ContentPresenter.ContentProperty, new TemplateBindingExtension(ViewDialogC.ContentProperty));
grid.AppendChild(content);
group.AppendChild(grid);
border.AppendChild(group);
this.SetValue(ViewDialogC.TemplateProperty, new ControlTemplate(typeof(ViewDialogC)) { VisualTree = border });
}
}
public static readonly DependencyProperty TitleProperty =
DependencyProperty.RegisterAttached("Title", typeof(string), typeof(ViewDialogC), new PropertyMetadata(" "));
public string Title { get { return (string)this.GetValue(TitleProperty); } set { this.SetValue(TitleProperty, value); } }
public static readonly DependencyProperty ContentWidthProperty =
DependencyProperty.RegisterAttached("ContentWidth", typeof(double), typeof(ViewDialogC), new PropertyMetadata(double.NaN));
public double ContentWidth { get { return (double)this.GetValue(ContentWidthProperty); } set { this.SetValue(ContentWidthProperty, value); } }
public static readonly DependencyProperty ContentHeightProperty =
DependencyProperty.RegisterAttached("ContentHeight", typeof(double), typeof(ViewDialogC), new PropertyMetadata(double.NaN));
public double ContentHeight { get { return (double)this.GetValue(ContentHeightProperty); } set { this.SetValue(ContentHeightProperty, value); } }
public virtual void OnClosing(CancelEventArgs e) { }
public virtual void Close() { }
}
}
実装 xaml コード:
<my:ViewDialogX Title="Test">
<Button Content="Button" />
</my:ViewDialogX>
<my:ViewDialogC Title="Test">
<Button Content="Button" />
</my:ViewDialogC>
余分なスタイル:
<SolidColorBrush x:Key="ControlBackgroundBrush" Color="#333333" />
<SolidColorBrush x:Key="NormalBackgroundBrush" Color="#595959" />
<LinearGradientBrush x:Key="ShineBrush" StartPoint="0,0.042" EndPoint="0,0.971">
<GradientStop Color="#59FFFFFF" Offset="0" />
<GradientStop Color="#26FFFFFF" Offset="0.467" />
<GradientStop Color="#00FFFFFF" Offset="0.475" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="HoverShineBrush" StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#4CFFFFFF" Offset="0" />
<GradientStop Color="#26FFFFFF" Offset="0.467" />
<GradientStop Color="#10FFFFFF" Offset="0.475" />
<GradientStop Color="#10FFFFFF" Offset="0.856" />
<GradientStop Color="#26FFFFFF" Offset="1" />
</LinearGradientBrush>
<SolidColorBrush x:Key="DisabledForegroundBrush" Color="#ADADAD" />
<SolidColorBrush x:Key="DisabledBackgroundBrush" Color="#787878" />
<SolidColorBrush x:Key="DisabledBorderBrush" Color="#AAA" />
<Style TargetType="{x:Type GroupBox}" BasedOn="{x:Null}">
<Setter Property="Background" Value="{x:Null}" />
<Setter Property="Foreground" Value="White" />
<Setter Property="BorderBrush" Value="{DynamicResource ControlBackgroundBrush}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Padding" Value="3" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupBox}">
<DockPanel>
<Grid x:Name="HeaderGrid" DockPanel.Dock="Top">
<Border x:Name="BackgroundElement" Background="{DynamicResource NormalBackgroundBrush}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="3" />
<Border x:Name="ShineElement" Background="{DynamicResource ShineBrush}" BorderThickness="0" Margin="1" CornerRadius="3" />
<Border x:Name="ShineBorderElement" BorderBrush="{DynamicResource HoverShineBrush}" BorderThickness="1" CornerRadius="2" Margin="{TemplateBinding BorderThickness}" />
<ContentPresenter x:Name="ContentElement" SnapsToDevicePixels="True" ContentSource="Header" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="4" RecognizesAccessKey="True" />
</Grid>
<Border DockPanel.Dock="Bottom" Margin="0,-1,0,0" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="3">
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Margin="{TemplateBinding Padding}" />
</Border>
</DockPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="{DynamicResource DisabledForegroundBrush}" />
<Setter Property="Background" Value="{DynamicResource DisabledBackgroundBrush}" TargetName="BackgroundElement" />
<Setter Property="BorderBrush" Value="{DynamicResource DisabledBorderBrush}" TargetName="ShineBorderElement" />
<Setter Property="Opacity" TargetName="HeaderGrid" Value="0.75" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
もう一度私の質問は: ViewDialogX と ViewDialogC の出力が同じではないのはなぜですか?
(どういうわけか ViewDialogC はグループボックスの前景を編集しています。)
編集:
この行でフォアグラウンドの変更の原因を見つけました。
group.SetResourceReference(GroupBox.BackgroundProperty, "ControlBackgroundBrush");
(私が達成しようとしていることについては、ViewDialogX.xaml を参照してください)
背景を特定の色に設定したり、テンプレートの親プロパティにバインドしたりすることはできますが、FrameworkElementFactory がプロパティの動的リソース タイプを取得すると、前景が TemplateParent から継承されます。これはバグですか?