I have a derived class (i hope i have created correctly)
<ToggleButton x:Class="Project.QuestionControls.spriteToggleButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
xmlns:local="clr-Project.QuestionControls"
x:Name="spriteButton"
HorizontalAlignment="Center" Height="57" Width="294" VerticalAlignment="Center" d:LayoutOverrides="VerticalAlignment" IsEnabled="True">
<ToggleButton.Resources>
<Style x:Key="PhoneButtonBase" TargetType="ButtonBase">
<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="10,3,10,5"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ButtonBase">
<Grid Background="Transparent">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver"/>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentContainer">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneBackgroundBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="ButtonBackground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneForegroundBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ButtonBackground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneForegroundBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentContainer">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ButtonBackground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="ButtonBackground">
<DiscreteObjectKeyFrame KeyTime="0" Value="Transparent"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="ButtonBackground" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CornerRadius="0" Margin="{StaticResource PhoneTouchTargetOverhang}">
<ContentControl x:Name="ContentContainer" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="RectToggleButton" BasedOn="{StaticResource PhoneButtonBase}" TargetType="ToggleButton">
<Setter Property="Padding" Value="8"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Grid Background="Transparent" HorizontalAlignment="Center">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled"/>
<VisualState x:Name="MouseOver"/>
<VisualState x:Name="Pressed">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="Highlighted" d:IsOptimized="True"/>
<DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="Idle" d:IsOptimized="True"/>
<DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="Selected" d:IsOptimized="True"/>
</Storyboard>
</VisualState>
开发者_开发技巧 </VisualStateGroup>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Unchecked">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="Idle" d:IsOptimized="True"/>
<DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="Highlighted" d:IsOptimized="True"/>
<DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="Selected" d:IsOptimized="True"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Checked">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="Selected" d:IsOptimized="True"/>
<DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="Idle" d:IsOptimized="True"/>
<DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="Highlighted" d:IsOptimized="True"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<!-- any bindings here don't work -->
<local:spriteView x:Name="Idle" Width="294" Height="57" HorizontalAlignment="Center" Sprite="{Binding idleSprite}" />
<local:spriteView x:Name="Selected" Width="294" Height="57" HorizontalAlignment="Center" Sprite="{Binding selectedSprite}" />
<local:spriteView x:Name="Highlighted" Width="294" Height="57" HorizontalAlignment="Center" Sprite="{Binding highlightedSprite}" />
<ContentControl x:Name="Content" Content="{TemplateBinding Content}" Margin="70,8,71,15" d:LayoutOverrides="Width, Height" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ToggleButton.Resources>
<ToggleButton.Style>
<StaticResource ResourceKey="RectToggleButton"/>
</ToggleButton.Style>
</ToggleButton>
When I do {Binding idleSprite}
the binding doesn't do anything, I even tried with a string property to show up in a TextBlock but to no avail.
This is what my code looks behind for this control.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Media.Imaging;
using System.Windows.Controls.Primitives;
using System.Xml.Serialization;
namespace Project.QuestionControls
{
public partial class spriteToggleButton : ToggleButton
{
public Quiz.Sprite idleSprite { get; set; }
public static DependencyProperty idleSpriteProperty = DependencyProperty.Register(
"idleSprite", typeof(Quiz.Sprite), typeof(spriteToggleButton), new PropertyMetadata(new Quiz.Sprite(){ rect = new Rect(0,0,0,0), spriteSheet = "default.png" }
));
public Quiz.Sprite selectedSprite { get; set; }
public static DependencyProperty selectedSpriteProperty = DependencyProperty.Register(
"selectedSprite", typeof(Quiz.Sprite), typeof(spriteToggleButton), new PropertyMetadata(new Quiz.Sprite() { rect = new Rect(0, 0, 0, 0), spriteSheet = "default.png" }
));
public Quiz.Sprite highlightedSprite { get; set; }
public static DependencyProperty highlightedSpriteProperty = DependencyProperty.Register(
"highlightedSprite", typeof(Quiz.Sprite), typeof(spriteToggleButton), new PropertyMetadata(new Quiz.Sprite() { rect = new Rect(0, 0, 0, 0), spriteSheet = "default.png" }
));
public spriteToggleButton()
{
InitializeComponent();
}
public Dictionary<string, Quiz.Sprite> Sprites
{
get { return (Dictionary<string,Quiz.Sprite>)GetValue(SpritesProperty); }
set { SetValue(SpritesProperty, value); }
}
public static DependencyProperty SpritesProperty = DependencyProperty.Register(
"Sprites", typeof(Dictionary<string, Quiz.Sprite>), typeof(spriteToggleButton), new PropertyMetadata(new Dictionary<string, Quiz.Sprite>(), OnSpritesPropertyValueChanged));
private static void OnSpritesPropertyValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = d as spriteToggleButton;
var sprites = e.NewValue as Dictionary<string, Quiz.Sprite>;
control.idleSprite = sprites["idle"];
control.selectedSprite = sprites["selected"];
control.highlightedSprite = sprites["highlighted"];
}
public string Text { get { return (string)GetValue(TextProperty); } set { SetValue(TextProperty, value); } }
public static DependencyProperty TextProperty = DependencyProperty.Register(
"Text", typeof(string), typeof(spriteToggleButton), new PropertyMetadata("", OnTextPropertyValueChanged));
private static void OnTextPropertyValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = d as spriteToggleButton;
var contentText = e.NewValue as string;
control.spriteButton.Content = contentText;
}
public Boolean Selected { get { return (Boolean)GetValue(SelectedProperty); } set { SetValue(SelectedProperty, value); } }
public static DependencyProperty SelectedProperty = DependencyProperty.Register(
"Selected", typeof(Boolean), typeof(spriteToggleButton), new PropertyMetadata(false, OnSelectedPropertyValueChanged));
private static void OnSelectedPropertyValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = d as spriteToggleButton;
var selectedValue = (Boolean)e.NewValue;
control.spriteButton.IsChecked = selectedValue;
}
}
}
OnSpritesPropertyValueChanged
runs but the bindings still don't work, I even add a Loaded
event to check and the Sprites property was the defaults instead of what I had set it to (but maybe Loaded
runs before dependencyproperties are set)
It stopped working around the time I updated the UserControl into a derived ToggleButton, which I may have done wrong.
I hope this is enough detail to fix this issue.
In the ListBox that used the spriteToggleButton I send properties and they get sent down perfectly like this.
<local:spriteToggleButton HorizontalAlignment="Center" Text="{Binding text}" Sprites="{Binding Path=DataContext.UISprites, ElementName=questionField}" Selected="{Binding Selected}" Checked="optionChecked" />
Except when I repeat the process inside of spriteToggleButton but i have dependency properties registered there, so maybe there's a missing step with datacontext.
精彩评论