2

私は xaml クラスを構築しましたが、それを抽象基本クラスとして使用したい場合は、xaml なしで構築する必要があることに気付きました。しかし、xaml から C# への変換が完了したとき、結果は同じではありませんでした。

例: 前景が同じではありません。(左がViewDialogX、右がViewDialogC)

xaml と c# インスタンス

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 から継承されます。これはバグですか?

4

1 に答える 1

2

Microsoft WPF 開発チームに連絡しました。彼らはこれをバグとして認めていますが、優先度は低く、修正される可能性は低いとしています。

この例の回避策: 別のコントロールを使用して *.SetResourceReference 呼び出しを取得し、GroupBox の代わりに背景を描画します。

于 2012-10-21T19:28:53.927 に答える