2011-12-28 14 views
27

Obecnie pracuję nad prostym niestandardowym przyciskiem, który wykorzystuje obrazy dostarczone przez użytkownika jako tło dla naciśniętych i normalnych stanów. Mam wiele przycisków, więc zdecydowałem się napisać przycisk niestandardowy i zaimplementować dwie właściwości dla obrazów wciśniętych i normalnych stanów.TemplateBinding do DependencyProperty na niestandardowej kontrolce nie działa

Oto kod używam

public partial class ThemeableButton : Button 
{ 
    public ThemeableButton() 
    { 
     InitializeComponent(); 
    } 


    public static readonly DependencyProperty PressedContentBackgroundSourceProperty = DependencyProperty.Register(
        "PressedContentBackgroundSource", typeof(ImageSource), typeof(ThemeableButton), null); 
    public ImageSource PressedContentBackgroundSource 
    { 
     get { return (ImageSource)GetValue(PressedContentBackgroundSourceProperty); } 
     set 
     { 
      (value as BitmapImage).CreateOptions = BitmapCreateOptions.BackgroundCreation; 
      SetValue(PressedContentBackgroundSourceProperty, value); 
     } 
    } 


    public static readonly DependencyProperty NormalContentBackgroundSourceProperty = 
     DependencyProperty.Register("NormalContentBackgroundSource", typeof(ImageSource), typeof(ThemeableButton), null); 

    public ImageSource NormalContentBackgroundSource 
    { 
     get { return (ImageSource)GetValue(NormalContentBackgroundSourceProperty); } 
     set 
     { 
      (value as BitmapImage).CreateOptions = BitmapCreateOptions.BackgroundCreation; 
      SetValue(NormalContentBackgroundSourceProperty, value); 
     } 
    } 
} 

pisałem styl dla tego przycisku następująco

 <Style x:Key="ThemeableButtonTemplate" TargetType="MJbox_UIComponents_Controls:ThemeableButton"> 
     <Setter Property="Background" Value="Transparent"/> 
     <Setter Property="BorderBrush" Value="{StaticResource PhoneForegroundBrush}"/> 
     <Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/> 
     <Setter Property="BorderThickness" Value="{StaticResource PhoneBorderThickness}"/> 
     <Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilySemiBold}"/> 
     <Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMediumLarge}"/> 
     <Setter Property="Padding" Value="0"/> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="MJbox_UIComponents_Controls:ThemeableButton"> 
        <Grid> 
         <VisualStateManager.VisualStateGroups> 
          <VisualStateGroup x:Name="CommonStates"> 
           <VisualState x:Name="Normal"> 
            <Storyboard> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Source" Storyboard.TargetName="ButtonBackground"> 
              <DiscreteObjectKeyFrame KeyTime="0" Value="{TemplateBinding NormalContentBackgroundSource}"> 
              </DiscreteObjectKeyFrame> 
             </ObjectAnimationUsingKeyFrames> 
            </Storyboard> 
           </VisualState> 
           <VisualState x:Name="Pressed"> 
            <Storyboard> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Source" Storyboard.TargetName="ButtonBackground"> 
              <DiscreteObjectKeyFrame KeyTime="0" Value="{TemplateBinding PressedContentBackgroundSource}"> 
              </DiscreteObjectKeyFrame> 
             </ObjectAnimationUsingKeyFrames> 
            </Storyboard> 
           </VisualState> 
          </VisualStateGroup> 
         </VisualStateManager.VisualStateGroups> 
         <Border BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CornerRadius="0"> 
          <Image x:Name="ButtonBackground" Stretch="None" Source="{TemplateBinding NormalContentBackgroundSource}"/> 
         </Border>  
        </Grid> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 

Próbowałem prosty przykład

<Controls:ThemeableButton Style="{StaticResource ThemeableButtonTemplate}" x:Name="btnDidntNeedIt" NormalContentBackgroundSource="{Binding Source={StaticResource DefaultTheme}, Path=DidntHaveButtonUnselected}" 
            PressedContentBackgroundSource="{Binding Source={StaticResource DefaultTheme}, Path=DidntHaveButtonSelected}" 
     /> 

ale obraz nie pokazuje, próbowałem przez usunięcie TemplateBinding z stylu i zastąpiłem go względnym źródłem do obrazu plik i działało dobrze. Po prostu nie chcę tworzyć niestandardowego stylu dla każdego przycisku w aplikacji. Jakiekolwiek możliwe obejście?

Odpowiedz

71

Napotkałem to wcześniej, TemplateBinding nie działa dla niestandardowych właściwości zależności na elementach sterujących. Zobacz te pytania związane z:

issues with template binding and binding of custom component

TemplateBinding does not work in certain cases(when using TranslateTransform)

zawsze stosować zamiast tego:

{Binding MyProperty, RelativeSource={RelativeSource TemplatedParent}} 

Jest semantycznie taka sama jak TemplateBinding, a także może obsługiwać konwertery wartości itp ..

+0

Dzięki Colin, działał dobrze i zaoszczędził mi tonów pracy – Waleed

+0

To jest odpowiedź, która zadziałała dla mnie też. Żałuję, że TemplateBinding nie zadziałało i że niektóre tajemnice i arbitralność zostały rozwiane. – TernaryTopiary

+0

"... TemplateBinding nie działa dla niestandardowych właściwości zależności w kontrolkach [.]" To działa dla mnie. '" w moim kontrolerze niestandardowym 'ControlTemplate' wypełnia' Rectangle' z moją niestandardową właściwością zależności 'FillBrush', nawet pokazując tę ​​właściwość w arkuszu właściwości VS i wypełniając to, co ustawiłem to w czasie projektowania. Może to coś nowego od 2011 roku? W każdym razie teraz działa dobrze. (Ale uważaj na animacje do rzeczy, które nie są "Freezeable".) Nadal nie możesz tego zrobić.) –

Powiązane problemy