0

现在,我正在尝试弄清楚如何为ImageButton具有两种状态(按下和正常)以及Image为每个状态创建一个模板。

  1. 状态正常:显示图像“buttonname.png”,隐藏“buttonname_pressed.png”

  2. 按下状态:隐藏图像“buttonname.png”,显示“buttonname_pressed.png”

所以我StyleApplication.Resources.

应用程序资源:

<Style x:Key="ImageButton" TargetType="Button">

    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="Padding" Value="0"/>
    <Setter Property="BorderThickness" Value="0"/>

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Grid Background="Transparent" Height="90">
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="imageNormal">
                                        <DiscreteObjectKeyFrame KeyTime="0">
                                            <DiscreteObjectKeyFrame.Value>
                                                <Visibility>Visible</Visibility>
                                            </DiscreteObjectKeyFrame.Value>
                                        </DiscreteObjectKeyFrame>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="imagePressed">
                                        <DiscreteObjectKeyFrame KeyTime="0">
                                            <DiscreteObjectKeyFrame.Value>
                                                <Visibility>Collapsed</Visibility>
                                            </DiscreteObjectKeyFrame.Value>
                                        </DiscreteObjectKeyFrame>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Pressed">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="imageNormal">
                                        <DiscreteObjectKeyFrame KeyTime="0">
                                            <DiscreteObjectKeyFrame.Value>
                                                <Visibility>Collapsed</Visibility>
                                            </DiscreteObjectKeyFrame.Value>
                                        </DiscreteObjectKeyFrame>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="imagePressed">
                                        <DiscreteObjectKeyFrame KeyTime="0">
                                            <DiscreteObjectKeyFrame.Value>
                                                <Visibility>Visible</Visibility>
                                            </DiscreteObjectKeyFrame.Value>
                                        </DiscreteObjectKeyFrame>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>

                    <Image x:Name="imageNormal"  Source="{Binding ???}"  Stretch="UniformToFill" />
                    <Image x:Name="imagePressed" Source="{Binding ???}" Stretch="UniformToFill" />

                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

现在我想ImageButton用不同的图像创建3个不同的s,这是我不明白的。(°へ°)

我尝试使用BindingAttachedProperty...

图片源的绑定:

Source="{Binding SourceNormal, RelativeSource={RelativeSource TemplatedParent}}"

附加属性:

namespace HTML5App1.Resources.AttachedProperty
{
    public static class ImageButton
    {
        /////////////////////// SourceNormal /////////////////////////////////////////////////////

        //----------------------------------------------------------------------------------------
        public static readonly DependencyProperty SourceNormal = DependencyProperty.RegisterAttached(
            "SourceNormal",
            typeof(string),
            typeof(ImageButton),
            new PropertyMetadata(null)
        );

        public static string GetSourceNormal(UIElement element)
        {
            if (element == null)
            {
                new ArgumentNullException("element");
            }
            return (string)element.GetValue(SourceNormal);
        }

        public static void SetSourceNormal(UIElement element, string value)
        {
            if (element == null)
            {
                new ArgumentNullException("element");
            }

            element.SetValue(SourceNormal, value);
        }
        //----------------------------------------------------------------------------------------

        /////////////////////// SourcePressed ////////////////////////////////////////////////////

        //----------------------------------------------------------------------------------------
        public static readonly DependencyProperty SourcePressed = DependencyProperty.RegisterAttached(
            "SourcePressed",
            typeof(string),
            typeof(ImageButton),
            new PropertyMetadata(null)
        );

        public static string GetSourcePressed(UIElement element)
        {
            if (element == null)
            {
                new ArgumentNullException("element");
            }
            return (string)element.GetValue(SourcePressed);
        }

        public static void SetSourcePressed(UIElement element, string value)
        {
            if (element == null)
            {
                new ArgumentNullException("element");
            }

            element.SetValue(SourcePressed, value);
        }
        //----------------------------------------------------------------------------------------
    }
}

MainPage.xaml:

xmlns:local="clr-namespace:HTML5App1.Resources.AttachedProperty"

<Button
    Style="{StaticResource ImageButton}"
    local:ImageButton.SourceNormal="/Assets/Images/button.png"
    local:ImageButton.SourcePressed="/Assets/Images/button_pressed.png"
    Grid.Column="1"
    Click="Button_Clicked"
    />

如果我构建应用程序,我会收到两个绑定的错误消息:

An exception of type 'System.IO.FileNotFoundException' occurred in mscorlib.ni.dll and wasn't handled before a managed/native boundary
System.Windows.Data Error: BindingExpression path error: 'SourceNormal' property not found on 'System.Windows.Controls.Button' 'System.Windows.Controls.Button' (HashCode=45028263). BindingExpression: Path='SourceNormal' DataItem='System.Windows.Controls.Button' (HashCode=45028263); target element is 'System.Windows.Controls.Image' (Name='imageNormal'); target property is 'Source' (type 'System.Windows.Media.ImageSource')..
System.Windows.Data Error: BindingExpression path error: 'SourcePressed' property not found on 'System.Windows.Controls.Button' 'System.Windows.Controls.Button' (HashCode=45028263). BindingExpression: Path='SourcePressed' DataItem='System.Windows.Controls.Button' (HashCode=45028263); target element is 'System.Windows.Controls.Image' (Name='imagePressed'); target property is 'Source' (type 'System.Windows.Media.ImageSource')..

但我无法弄清楚我做错了什么 - 有人能指出我正确的方向吗?

其他问题:

  • 是否有一种“更简单”的方法可以从 Button 创建 ImageButton 模板 - 我可以访问ButtonNormalPressedVisualState 或收听它并更改 Image.Source(如果它是 Normal 或 Pressed)吗?

  • 是否有一种“更简单”的方式来访问Image.SourceGridButton,而不使用Bindings (在 XAML 或 C# 中)?

  • 有没有关于 XAML 中的绑定和模板的好教程,我是 XAML 的初学者

提前致谢 ;)

4

1 回答 1

1

以下应该有效:

<Image x:Name="imageNormal"  Source="{TemplateBinding local:ImageButton.SourcePressed}"  Stretch="UniformToFill" />

此外,您应该使用 ImageSource,而不是使用字符串作为两个附加属性的类型。

为了回答您的其他问题,您可以通过创建自定义控件继承按钮在代码中执行此操作,然后您可以使用称为 TemplatedPart 的名称访问样式内的所有元素。请参阅那里的示例(它是 WPF,但它对 wp 的工作方式完全相同)。但无论如何,我认为你目前的做法是正确的。

关于文章:这个msdn 文档通过一些示例提供了一个良好的开端,但不要谈论更高级的绑定 senario

在这里编辑是我测试并为我工作的完整代码:

依赖属性(将字符串切换到 ImageSource 并为 dep 属性和实际属性使用不同的名称):

public static class ImageButton
{



    /////////////////////// SourceNormal /////////////////////////////////////////////////////

    //----------------------------------------------------------------------------------------
    public static readonly DependencyProperty SourceNormalProperty = DependencyProperty.RegisterAttached(
        "SourceNormal",
        typeof(ImageSource),
        typeof(ImageButton),
        new PropertyMetadata(null)
    );

    public static ImageSource GetSourceNormal(UIElement element)
    {
        if (element == null)
        {
            new ArgumentNullException("element");
        }
        return (ImageSource)element.GetValue(SourceNormalProperty);
    }

    public static void SetSourceNormal(UIElement element, ImageSource value)
    {
        if (element == null)
        {
            new ArgumentNullException("element");
        }

        element.SetValue(SourceNormalProperty, value);
    }
    //----------------------------------------------------------------------------------------

    /////////////////////// SourcePressed ////////////////////////////////////////////////////

    //----------------------------------------------------------------------------------------
    public static readonly DependencyProperty SourcePressedProperty = DependencyProperty.RegisterAttached(
        "SourcePressed",
        typeof(ImageSource),
        typeof(ImageButton),
        new PropertyMetadata(null)
    );

    public static ImageSource GetSourcePressed(UIElement element)
    {
        if (element == null)
        {
            new ArgumentNullException("element");
        }
        return (ImageSource)element.GetValue(SourcePressedProperty);
    }

    public static void SetSourcePressed(UIElement element, ImageSource value)
    {
        if (element == null)
        {
            new ArgumentNullException("element");
        }

        element.SetValue(SourcePressedProperty, value);
    }
    //----------------------------------------------------------------------------------------
}

样式(只需使用上面解释的 TemplateBinding):

<Style x:Key="ImageButton" TargetType="Button">

        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="Padding" Value="0"/>
        <Setter Property="BorderThickness" Value="0"/>

        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Grid Background="Transparent" Height="90">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualState x:Name="Normal">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="imageNormal">
                                            <DiscreteObjectKeyFrame KeyTime="0">
                                                <DiscreteObjectKeyFrame.Value>
                                                    <Visibility>Visible</Visibility>
                                                </DiscreteObjectKeyFrame.Value>
                                            </DiscreteObjectKeyFrame>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="imagePressed">
                                            <DiscreteObjectKeyFrame KeyTime="0">
                                                <DiscreteObjectKeyFrame.Value>
                                                    <Visibility>Collapsed</Visibility>
                                                </DiscreteObjectKeyFrame.Value>
                                            </DiscreteObjectKeyFrame>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Pressed">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="imageNormal">
                                            <DiscreteObjectKeyFrame KeyTime="0">
                                                <DiscreteObjectKeyFrame.Value>
                                                    <Visibility>Collapsed</Visibility>
                                                </DiscreteObjectKeyFrame.Value>
                                            </DiscreteObjectKeyFrame>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="imagePressed">
                                            <DiscreteObjectKeyFrame KeyTime="0">
                                                <DiscreteObjectKeyFrame.Value>
                                                    <Visibility>Visible</Visibility>
                                                </DiscreteObjectKeyFrame.Value>
                                            </DiscreteObjectKeyFrame>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>

                        <Image x:Name="imageNormal"  Source="{TemplateBinding local:ImageButton.SourceNormal}"  Stretch="UniformToFill" />
                        <Image x:Name="imagePressed" Source="{TemplateBinding local:ImageButton.SourcePressed}" Stretch="UniformToFill" />

                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

按钮(无变化):

<Button Style="{StaticResource ImageButton  }" 
                local:ImageButton.SourceNormal="/Assets/ApplicationIcon.png"
                local:ImageButton.SourcePressed="/Assets/Tiles/FlipCycleTileLarge.png"/>
于 2013-09-18T19:21:24.960 回答