【问题标题】:Windows store app - XAML - One style with different imagesWindows 商店应用程序 - XAML - 具有不同图像的一种样式
【发布时间】:2014-05-01 10:34:12
【问题描述】:

我一直在查看blog,其中包含一些有关为应用栏按钮设置样式的信息。下面是我稍微编辑的样式之一。

<Page.Resources>
    <ResourceDictionary>
        <Style x:Key="TasksButtonStyle" TargetType="Button">
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="Foreground" Value="White"/>
            <Setter Property="BorderBrush" Value="Transparent"/>
            <Setter Property="FontFamily" Value="Segoe UI"/>
            <Setter Property="FontSize" Value="9"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <Grid>
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CommonStates">
                                    <VisualState x:Name="Normal"/>
                                    <VisualState x:Name="MouseOver"/>
                                    <VisualState x:Name="Pressed">
                                        <Storyboard>
                                            <ColorAnimation Duration="0" To="White" Storyboard.TargetProperty="(Ellipse.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="ButtonEllipse" />
                                            <ColorAnimation Duration="0" To="Black" Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="Glyph" />
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <StackPanel Orientation="Vertical">
                                <Grid  Margin="0,14,0,5" >
                                    <Ellipse x:Name="ButtonEllipse" Height="40" Width="40" Fill="Transparent" HorizontalAlignment="Center"
                                          Stroke="#FF00A5E7" StrokeThickness="2" VerticalAlignment="Center"/>
                                    <Image x:Name="ButtonImage" Source="/Assets/Image1.png" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                                </Grid>
                                <TextBlock Text="{TemplateBinding Content}" HorizontalAlignment="Center"
                                        FontFamily="Segoe UI" FontSize="12"/>
                            </StackPanel>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ResourceDictionary>
</Page.Resources>

我想多次使用这种风格,但我不确定是否有办法改变这一行的图像来源

<Image Source="/Assets/Image1.png" HorizontalAlignment="Center" VerticalAlignment="Center"/>

而不是简单地复制粘贴整个样式。

我想做这样的事情。 (我试过了,但似乎无效)

伪 XAML

<Button x:Uid="appbarOne" Click="NavButton_Click" Tag="Client.Pages.one" Style="{StaticResource TasksButtonStyle ButtonImage.Source="Assets/Image1"}" Content="Tasks"/>
<Button x:Uid="appbarTwo" Click="NavButton_Click" Tag="Client.Pages.two" Style="{StaticResource TasksButtonStyle ButtonImage.Source="Assets/Image2"}" Content="Tasks"/>
<Button x:Uid="appbarThree" Click="NavButton_Click" Tag="Client.Pages.three" Style="{StaticResource TasksButtonStyle ButtonImage.Source="Assets/Image3"}" Content="Tasks"/>
<Button x:Uid="appbarFour" Click="NavButton_Click" Tag="Client.Pages.four" Style="{StaticResource TasksButtonStyle ButtonImage.Source="Assets/Image4"}" Content="Tasks"/>

有没有办法我可以使用类似于Style="{StaticResource TasksButtonStyle ButtonImage.Source="Assets/Image4"}" 的方法来做到这一点?

【问题讨论】:

    标签: c# xaml windows-store-apps microsoft-metro winrt-xaml


    【解决方案1】:

    用这个替换自定义样式中的&lt;Image /&gt;

    <Image x:Name="ButtonImage" HorizontalAlignment="Center" VerticalAlignment="Center" Stretch="None"
           Source="{Binding Path=(local:AppBarButton.Image),RelativeSource={RelativeSource TemplatedParent}}"/>
    

    从样式中删除下一行,因为没有名为“字形”的元素

    <ColorAnimation Duration="0" To="Black" Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="Glyph" />
    

    添加一个名为AppBarButton 的类,其定义如下。它有一个附加属性Image。我们将使用它来提供从按钮标签到按钮样式的图像源。

    public class AppBarButton
    {
        public static string GetImage(DependencyObject obj)
        {
            return (string)obj.GetValue(ImageProperty);
        }
    
        public static void SetImage(DependencyObject obj, string value)
        {
            obj.SetValue(ImageProperty, value);
        }
    
        public static readonly DependencyProperty ImageProperty =
            DependencyProperty.RegisterAttached("Image", typeof(string), typeof(AppBarButton), new PropertyMetadata(string.Empty));
    }
    

    现在在你的 XAML 页面中添加这样的按钮,

    <StackPanel>
        <Button Style="{StaticResource TasksButtonStyle}" local:AppBarButton.Image="ms-appx:///Assets/Screenshot_2.png" />
        <Button Style="{StaticResource TasksButtonStyle}" local:AppBarButton.Image="ms-appx:///Assets/Screenshot_3.png" />
        <Button Style="{StaticResource TasksButtonStyle}" local:AppBarButton.Image="ms-appx:///Assets/Screenshot_4.png" />
    </StackPanel>
    

    这里的local 指的是AppBarButton 类的命名空间。对我来说是

    <Page
        x:Class="App2.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:App2"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    

    因为我在App2 命名空间中声明了AppBarButton 类。

    【讨论】:

    • 会试一试。我自己注意到了 Glyph 问题,我认为在我从博客中复制的原始示例中,&lt;TextBlock /&gt; 元素应该命名为 Glyph。不过好地方!
    • 当然!我的Common 命名空间中有MyAppBarButton 类,并且在包含MyApp.Common:MyAppBarButton.Image="ms-appx:///Assets/blue_32_clipboard.png" 的行上出现The namespace prefix MyApp.Common is not defined 错误。有什么想法是我可能缺少的吗?
    • 你必须在&lt;Page ... /&gt;中定义xmlns:common="using:MyApp.Common"
    • 现在我收到 Failed to assign to property 'MyApp.Common.MyAppBarButton.Image'. [Line: 63 Position: 175] 第 63 行的运行时错误,包括:common:MyAppBarButton.Image="ms-appx:///Assets/blue_32_clipboard.png"。有什么想法吗?
    • 请确保您正确地遵循了我的解决方案,尤其是在AppBarButton 按钮的类和样式中。
    【解决方案2】:

    您可以使用将样式放在新的 xaml 文件中,例如 globalstyles.xaml。 然后在您的页面中引用 xaml 文件,如下所示,

     <UserControl.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary  Source="../Styles.xaml"></ResourceDictionary>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </UserControl.Resources>
    

    在页面中引用样式后,您可以使用以下样式

    <Button Name="cancel" Content="cancel" Style="{StaticResource CancelButtonStyle}" 
                       HorizontalAlignment="Right" Margin="5,45,5,7" />
    
    <Button Name="Submit" Content="Submit" Style="{StaticResource SubmitButtonStyle}" 
                       HorizontalAlignment="Right" Margin="5,45,5,7" />
    

    希望这会有所帮助。

    【讨论】:

      【解决方案3】:

      您可以定义一个将使用附加属性的模板。在代码中,为附加属性添加一个新类:

      public class AssociatedObject
      {
          public static ImageSource GetImage(DependencyObject obj)
          {
              return (ImageSource)obj.GetValue(ImageProperty);
          }
      
          public static void SetImage(DependencyObject obj, ImageSource value)
          {
              obj.SetValue(ImageProperty, value);
          }
      
          // Using a DependencyProperty as the backing store for Image.  This enables animation, styling, binding, etc...
          public static readonly DependencyProperty ImageProperty =
              DependencyProperty.RegisterAttached("Image", typeof(ImageSource), typeof(AssociatedObject), new PropertyMetadata(null));
      }
      

      然后,在您的模板中,对父对象执行TemplateBinding(为简洁起见,删除大部分样式):

          <Style x:Key="ButtonStyle1" TargetType="Button">
              <Setter Property="Template">
                  <Setter.Value>
        // REMOVED A BUNCH HERE
                               <Border x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Margin="3">
                                  <Grid>
        // YOUR IMAGE IS HERE
                                      <Image Source="{TemplateBinding local:AssociatedObject.Image}" Stretch="None"/>
                                      <ContentPresenter x:Name="ContentPresenter" AutomationProperties.AccessibilityView="Raw" ContentTemplate="{TemplateBinding ContentTemplate}" ContentTransitions="{TemplateBinding ContentTransitions}" Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                                 </Grid>
                              </Border>
                     </ControlTemplate>
       // REMOVED A BUNCH HERE
                   </Setter.Value>
              </Setter>
          </Style>
      

      查看Grid 中的Image 元素。它包含一个到父级的 TemplateBinding。然后,当您在 XAML 中实例化您的按钮时,您只需说出 AssociatedObject.Image 的设置:

          <Button Style="{StaticResource ButtonStyle1}" local:AssociatedObject.Image="/assets/Logo.scale-100.png"></Button>
      

      【讨论】:

        【解决方案4】:

        如果你想要一个 appbar 按钮的外观,你应该看看 AppBarButton 类,它有你想要的一切。然后,您可以使用 Icon 属性来使用 200 多种内置图标样式之一,或者也可以通过 PathIcon、SymbolIcon 或 BitmapIcon 类提供您自己的样式。

        见:http://timheuer.com/blog/archive/2013/10/29/use-new-appbarbutton-in-windows-8-1-commandbar.aspx

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多