2012-10-14 75 views
2

我構建了一個xaml類,然後意識到如果我想將它用作抽象基類,它必須在沒有xaml的情況下構建。但是當我完成將xaml轉換爲C#時,結果不會輸出相同的結果。生成的Xaml代碼和自定義C#代碼不會生成相同的輸出?

E.g.前景不一樣。 (ViewDialogX上左,上ViewDialogC右側)

xaml vs c# instances

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我試圖實現)

我可以很難設置背景爲一個特定的c olor或甚至將其綁定到模板父屬性,但是當FrameworkElementFactory獲取動態資源類型的屬性時,則前景將從TemplateParent繼承。這是一個錯誤?

回答

2

我已經聯繫了Microsoft WPF開發團隊。他們承認這是一個錯誤,但已經將其列爲低優先級並且不太可能被修復。

我的這個例子的工作:使用另一個控件來調用* .SetResourceReference並繪製背景,而不是GroupBox。

+0

偉大的你調查,報告和告訴這裏。 – trapicki