2010-12-01 5 views
2

J'essaie de créer un CustomControl dérivé de Button, qui s'affiche simplement sous la forme d'un rectangle de couleur. Je veux avoir deux propriétés sur mon contrôle que je peux définir, qui spécifient la couleur normale (ColdColor), et une autre couleur qui sera utilisée lorsque la souris est au-dessus du contrôle (HotColor).Relier la couleur du pinceau aux propriétés dans ControlTemplate

Je n'arrive pas à comprendre comment régler la liaison entre la couleur de la brosse et les propriétés du contrôle. Ceci est mon code:

generic.xaml:

<Style TargetType="{x:Type local:TestCustomControl}"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type local:TestCustomControl}"> 
       <Border BorderBrush="{TemplateBinding BorderBrush}" 
         BorderThickness="{TemplateBinding BorderThickness}" 
         Name="MyBorder"> 
        <Border.Background> 
         <!-- This works: --> 
         <!--<SolidColorBrush Color="Green" />--> 

         <!-- This doesn't work: --> 
         <SolidColorBrush Color="{TemplateBinding ColdColor}" /> 
        </Border.Background> 
        <VisualStateManager.VisualStateGroups> 
         <VisualStateGroup x:Name="CommonStates"> 
          <VisualState x:Name="Normal"/> 
          <VisualState x:Name="MouseOver"> 
           <Storyboard> 
            <!-- This works: --> 
            <!--<ColorAnimation Storyboard.TargetProperty="Background.Color" Storyboard.TargetName="MyBorder" To="Red" Duration="0:0:0.2"/>--> 

            <!-- This doesn't work: --> 
            <ColorAnimation Storyboard.TargetProperty="Background.Color" Storyboard.TargetName="MyBorder" To="{TemplateBinding HotColor}" Duration="0:0:0.2"/> 
           </Storyboard> 
          </VisualState> 
         </VisualStateGroup> 
        </VisualStateManager.VisualStateGroups> 
       </Border> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

TestCustomControl.cs:

public class TestCustomControl : Button 
{ 
    static TestCustomControl() 
    { 
     DefaultStyleKeyProperty.OverrideMetadata(typeof(TestCustomControl), new FrameworkPropertyMetadata(typeof(TestCustomControl))); 
    } 

    public Color HotColor 
    { 
     get { return (Color)GetValue(HotColorProperty); } 
     set { SetValue(HotColorProperty, value); } 
    } 

    // Using a DependencyProperty as the backing store for HotColor. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty HotColorProperty = 
     DependencyProperty.Register("HotColor", typeof(Color), typeof(TestCustomControl), new UIPropertyMetadata(new Color())); 

    public Color ColdColor 
    { 
     get { return (Color)GetValue(ColdColorProperty); } 
     set { SetValue(ColdColorProperty, value); } 
    } 

    // Using a DependencyProperty as the backing store for ColdColor. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty ColdColorProperty = 
     DependencyProperty.Register("ColdColor", typeof(Color), typeof(TestCustomControl), new UIPropertyMetadata(new Color())); 
} 

Utilisation dans MainWindow.xaml:

<my:TestCustomControl ColdColor="#FF0000AF" HotColor="#FFFF00AF"/> 

EDIT: Dire que " ne fonctionne pas "signifie que TestCustomControl est entièrement transparent.

Répondre

3

Il n'y a pas de problème évident (afaik), je changerais ce morceau de code:

UIPropertyMetadata(new Color()) 

à

UIPropertyMetadata(Colors.White) 

et voir si son 'nouveau Color()' qui est le problème

EDIT -

si le di ci-dessus travail dnt, essayez de changer ce

<SolidColorBrush Color="{TemplateBinding ColdColor}" /> 

à cette

<SolidColorBrush Color="{Binding 
    RelativeSource={RelativeSource TemplatedParent}, 
    Path=ColdColor}" /> 
+0

Merci, mais encore ne fonctionne pas, c'est-à-dire que TestCustomControl est entièrement transparent. – NPVN

+0

J'ai modifié par des suggestions pour inclure une nouvelle idée –

+0

Merci beaucoup: Que la moitié fonctionne! Cela signifie que cela fonctionne pour le pinceau spécifié dans l'élément Border.Background. Le ColorAnimation ne fait rien; le contrôle continue à être peint avec ColdColor. EDIT: J'ai appliqué le même changement à l'animation, bien sûr, en changeant le chemin vers HotColor. – NPVN

0

Le directeur de l'état visuel a une limitation liée: il ne peut pas animer les propriétés définies par une liaison. Donc, vous essayez simplement de faire quelque chose qui ne peut pas être fait.

Ce que vous pouvez faire est de dupliquer les éléments et d'utiliser l'opacité pour faire la transition. Ce qui suit montre comment vous le faire avec le VSM et opacités:

Compte tenu d'un TwoColorBox de contrôle personnalisé avec des propriétés de dépendance

Color ColorOne 
Color ColorTwo 

et avec états visuels:

ColorOne 
ColorTwo 

Le modèle de contrôle suivante faire ce que vous voulez sans transparence traverser

<ControlTemplate TargetType="{x:Type view:TwoColorBox}"> 
    <Grid Background="{TemplateBinding Background}"> 
     <VisualStateManager.VisualStateGroups> 
      <VisualStateGroup x:Name="ColorStates"> 
       <VisualStateGroup.Transitions> 
        <VisualTransition GeneratedDuration="0:0:1"/> 
       </VisualStateGroup.Transitions> 
       <VisualState x:Name="ColorOne"/> 
       <VisualState x:Name="ColorTwo"> 
        <Storyboard> 
         <DoubleAnimationUsingKeyFrames 
          Storyboard.TargetProperty="(UIElement.Opacity)" 
          Storyboard.TargetName="borderTwo"> 
          <EasingDoubleKeyFrame KeyTime="0" Value="1"/> 
         </DoubleAnimationUsingKeyFrames> 
        </Storyboard> 
       </VisualState> 
      </VisualStateGroup> 
     </VisualStateManager.VisualStateGroups> 
     <Border 
      x:Name="borderOne" 
      BorderThickness="{TemplateBinding BorderThickness}"> 
      <Border.BorderBrush> 
       <SolidColorBrush 
        Color="{Binding ColorOne, RelativeSource={RelativeSource TemplatedParent}}"/> 
      </Border.BorderBrush> 
     </Border> 
     <Border 
      x:Name="borderTwo" 
      BorderThickness="{TemplateBinding BorderThickness}" Opacity="0"> 
      <Border.BorderBrush> 
       <SolidColorBrush 
        Color="{Binding ColorTwo, RelativeSource={RelativeSource TemplatedParent}}"/> 
      </Border.BorderBrush> 
     </Border> 
    </Grid> 
</ControlTemplate> 
Questions connexes