【问题标题】:Accessing ControlTemplate Style In Custom Application.Resources在自定义 Application.Resources 中访问 ControlTemplate 样式
【发布时间】:2018-07-21 00:35:59
【问题描述】:

我为一个按钮创建了一个模板样式,我想为我的项目中的每个专辑调用它。

<Application.Resources>
    <Style x:Key="CustomButtonLarge" TargetType="Button">
        <Setter Property="Background" Value="Pink" />
        <Setter Property="Foreground" Value="White" />
        <Setter Property="Width" Value="300" />
        <Setter Property="Height" Value="100" />
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="VerticalAlignment" Value="Top" />
        <Setter Property="Height" Value="300" />
        <Setter Property="Width" Value="200" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Grid x:Name="AlbumContentGrid">

                        <Grid.RowDefinitions>
                            <RowDefinition Height="200"/>
                            <RowDefinition Height="50"/>
                            <RowDefinition Height="50"/>
                        </Grid.RowDefinitions>

                        <Image Grid.Row="0" source="null" x:Key="albumCover" />
                        <Textblock Grid.Row="1" x:Key="Title" Style="{StaticResources CustomForegroundTitleText}"/>
                        <Textblock Grid.Row="2" x:Key="SubTitle" Style="{StaticResources CustomForegroundSubTitleText}" />
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>


</Application.Resources>

当我在后面的代码中时,我想为每个专辑创建这个按钮。所以如果有3张专辑,我想做一个for循环...

int numberOfButtons= 3;

private void Page_Loaded(object sender, RoutedEventArgs e)
    {

        for (int i = 0; i < numberOfButtons; i++)
        {
            Button btn = new Button();
            Style style = App.Current.Resources["CustomButtonLarge"] as Style;

            btn.Style = style;

            StackAlbums.Children.Add(btn);
        }

    }

StackAlbums 是主网格中的 stackPanel。出于某种原因,我在跑步时没有得到任何东西。

但我也不确定如何访问“albumCover”图像,以便我可以将源更改为代码中所需的任何内容,并更改标题和子标题文本块的文本值。

【问题讨论】:

  • 您的 CustomButtonLarge 没有权利,您不应该在 TextBlock 中使用 x:Key="SubTitle",它是 TextBlock 而不是 Textblock

标签: c# xaml uwp win-universal-app controltemplate


【解决方案1】:

首先,您应该修复Style具有重复属性widthHeight的Style。

然后你应该为背景制作效果。您应该将其绑定到 Grid。

                    <Grid x:Name="AlbumContentGrid" Background="{TemplateBinding Background}" >

Grid应该设置Background绑定Button背景。

你应该删除所有的x:Key

如果你想在代码中设置图像,你应该创建数据上下文。

我开设了一个课程Foo 来做这件事。

public class Foo
{
    public BitmapImage Image { get; set; }

    public string Title { get; set; }

    public string  SubTitle { get; set; }
}

我应该在添加按钮时设置它。

    private void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
        int numberOfButtons = 3;


        for (int i = 0; i < numberOfButtons; i++)
        {
            var foo = new Foo
            {
                Image = new BitmapImage(new Uri("ms-appx:///Assets/Square44x44Logo.scale-200.png")),
                Title = "title" + i,
                SubTitle = i.ToString()
            };

            Button btn = new Button();
            Style style = Application.Current.Resources["CustomButtonLarge"] as Style;

            btn.Style = style;

            btn.DataContext = foo;

            StackAlbums.Children.Add(btn);
        }
    }

代码使用Square44x44Logo.scale-200.png,你可以更改它。

那么我应该使用bind来绑定数据上下文,CustomButtonLarge的所有代码都是

<Application.Resources>
    <Style x:Key="CustomButtonLarge" TargetType="Button">
        <Setter Property="Background" Value="Black" />
        <Setter Property="Foreground" Value="White" />
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="VerticalAlignment" Value="Top" />
        <Setter Property="Margin" Value="10,10,10,10"></Setter>
        <Setter Property="Height" Value="200" />
        <Setter Property="Width" Value="100" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button" >
                    <Grid x:Name="AlbumContentGrid" Background="{TemplateBinding Background}" >
                        <Grid.RowDefinitions>
                            <RowDefinition Height="200*"/>
                            <RowDefinition Height="50*"/>
                            <RowDefinition Height="50*"/>
                        </Grid.RowDefinitions>

                        <Image Grid.Row="0" x:Name="AlbumCover" Source="{Binding Path=Image}"/>
                        <TextBlock Grid.Row="1" x:Name="Title" Text="{Binding Title}" Foreground="{TemplateBinding Foreground}"/>
                        <TextBlock Grid.Row="2" x:Name="SubTitle" Text="{Binding SubTitle}" Foreground="{TemplateBinding Foreground}"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Application.Resources>

我尝试运行它并将屏幕剪辑给你。

如果你想添加点击事件你应该添加一些代码。

        for (int i = 0; i < numberOfButtons; i++)
        {
            var foo = new Foo
            {
                Image = new BitmapImage(new Uri("ms-appx:///Assets/Square44x44Logo.scale-200.png")),
                Title = "title" + i,
                SubTitle = i.ToString()
            };

            Button btn = new Button();
            Style style = Application.Current.Resources["CustomButtonLarge"] as Style;

            btn.Style = style;

            btn.DataContext = foo;

            StackAlbums.Children.Add(btn);

            btn.Click += Button_OnClick; // Make the click
        }

你应该写Button_OnClick并添加断点来知道用户点击了按钮。

    private void Button_OnClick(object sender, RoutedEventArgs e)
    {
        Debug.WriteLine(StackAlbums.Children.Count);
        Debug.WriteLine((StackAlbums.Children[0] as FrameworkElement)?.ActualWidth );
        Debug.WriteLine((StackAlbums.Children[0] as Button)?.Background?.ToString() ?? "");
    }

编辑

如果你想添加点击动画,你应该将代码添加到VisualStateManager.VisualStateGroups

                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal">
                                <Storyboard>
                                    <PointerUpThemeAnimation Storyboard.TargetName="AlbumContentGrid" />
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="PointerOver">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="AlbumContentGrid"
                                                                   Storyboard.TargetProperty="BorderBrush">
                                        <DiscreteObjectKeyFrame KeyTime="0"
                                                                Value="{ThemeResource SystemControlHighlightBaseMediumLowBrush}" />
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Title"
                                                                   Storyboard.TargetProperty="Foreground">
                                        <DiscreteObjectKeyFrame KeyTime="0"
                                                                Value="#aaaaaa" />
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="SubTitle"
                                                                   Storyboard.TargetProperty="Foreground">
                                        <DiscreteObjectKeyFrame KeyTime="0"
                                                                Value="#aaaaaa" />
                                    </ObjectAnimationUsingKeyFrames>
                                    <PointerUpThemeAnimation Storyboard.TargetName="AlbumContentGrid" />
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Pressed">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="AlbumContentGrid"
                                                                   Storyboard.TargetProperty="Background">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlBackgroundBaseMediumLowBrush}" />
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="AlbumContentGrid"
                                                                   Storyboard.TargetProperty="BorderBrush">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightTransparentBrush}" />
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Title"
                                                                   Storyboard.TargetProperty="Foreground">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseHighBrush}" />
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="SubTitle"
                                                                   Storyboard.TargetProperty="Foreground">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseHighBrush}" />
                                    </ObjectAnimationUsingKeyFrames>
                                    <PointerDownThemeAnimation Storyboard.TargetName="AlbumContentGrid" />
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>

您应该像下图一样将代码添加到 AlbumContentGrid。

添加代码时可以看到点击动画。

【讨论】:

  • 非常感谢您抽出时间来做这件事。只是一个快速的,由于某种原因,图像只显示在三个按钮之一上。任何想法为什么会这样?
  • 另外,按钮不可点击。
  • 好的,按钮现在都显示图片了,但是我不能点击它们...
  • 因为你应该添加一些来获取点击事件。
  • 如果你觉得这个答案对你有帮助,请点赞。
猜你喜欢
  • 1970-01-01
  • 2017-01-09
  • 2014-07-18
  • 1970-01-01
  • 1970-01-01
  • 2011-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多