Привязки не отображаются на моем связанном контроле - PullRequest
1 голос
/ 03 августа 2011

У меня есть производный класс (надеюсь, что я создал правильно)

    <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>

Когда я делаю {Binding idleSprite}, привязка ничего не делает, я даже пытался с помощью свойства строки показать в TextBlock, но безрезультатно.

Это то, что мой код ищет для этого элемента управления.

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 выполняется, но привязки по-прежнему не работают, я даже добавляю событие Loaded для проверки, и свойство Sprites было значением по умолчанию вместо того, что я его установил (но, возможно, Loaded запускается до свойства зависимости) установлены)

Он перестал работать примерно в то время, когда я обновил UserControl в производном ToggleButton, что я, возможно, сделал неправильно.

Надеюсь, этого достаточно, чтобы исправить эту проблему.

В ListBox, который использовал spriteToggleButton, я отправляю свойства, и они отправляются совершенно так.

<local:spriteToggleButton HorizontalAlignment="Center" Text="{Binding text}" Sprites="{Binding Path=DataContext.UISprites, ElementName=questionField}" Selected="{Binding Selected}" Checked="optionChecked" />

За исключением случаев, когда я повторяю процесс внутри spriteToggleButton, но у меня там зарегистрированы свойства зависимостей, так что, возможно, пропущен шаг с datacontext.

...