【问题标题】:WPF style/control template reuseWPF 样式/控件模板重用
【发布时间】:2010-06-19 08:10:57
【问题描述】:

我是 WPF 的新手,我想知道如何重用一些我必须避免重复的烦人的 xaml。

<Button Cursor="Hand" HorizontalAlignment="Left" Margin="0,0,0,0" x:Name="MyButton" Style="{StaticResource ButtonTemplate}" Width="286" Content="hi!" Focusable="False" IsTabStop="False"/>
<Button Cursor="Hand" HorizontalAlignment="Left" Margin="0,0,0,0" x:Name="MyButton2" Style="{StaticResource ButtonTemplate}" Width="286" Content="hi 2!" Focusable="False" IsTabStop="False"/>

我真的很想使用类似这个模板的东西:

<Style TargetType="{x:Type Button}" x:Key="ButtonTemplate">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Button}">
                        <Grid x:Name="btGrid">
                            <Path Cursor="Hand" HorizontalAlignment="Left" Stretch="Fill" Stroke="{x:Null}" Opacity="0" x:Name="path"/>
                            <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" RecognizesAccessKey="True" Visibility="Hidden" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top"/>
                        </Grid>
                        <ControlTemplate.Triggers>
                            <EventTrigger RoutedEvent="Button.PreviewMouseLeftButtonDown">
                                <EventTrigger.Actions>
                                    <BeginStoryboard>
                                        <Storyboard SlipBehavior="Slip" BeginTime="00:00:00">
                                            <MediaTimeline Source="{Binding StringFormat={}, Path=Name}" Storyboard.TargetName="{Binding StringFormat={}_wma, Path=Name}"/>
                                                    <ObjectAnimationUsingKeyFrames    Storyboard.TargetName="{Binding StringFormat=key{}, Path=Name}" Storyboard.TargetProperty="Visibility">
            <DiscreteObjectKeyFrame KeyTime="0">
                <DiscreteObjectKeyFrame.Value>
                    <Visibility>
                        Visible
                    </Visibility>
                </DiscreteObjectKeyFrame.Value>
            </DiscreteObjectKeyFrame>
        </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </BeginStoryboard>
                                </EventTrigger.Actions>
                            </EventTrigger>
                            <EventTrigger RoutedEvent="Button.PreviewMouseLeftButtonUp">
                                <EventTrigger.Actions>
                                    <BeginStoryboard>
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="{Binding StringFormat=key{}, Path=Name}" Storyboard.TargetProperty="Visibility">
            <DiscreteObjectKeyFrame KeyTime="0">
                <DiscreteObjectKeyFrame.Value>
                    <Visibility>
                        Hidden
                    </Visibility>
                </DiscreteObjectKeyFrame.Value>
            </DiscreteObjectKeyFrame>
        </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </BeginStoryboard>
                                </EventTrigger.Actions>
                            </EventTrigger>
                            <Trigger Property="IsFocused" Value="True"/>
                            <Trigger Property="IsDefaulted" Value="True"/>
                            <Trigger Property="IsMouseOver" Value="True"/>
                            <Trigger Property="IsPressed" Value="True"/>
                            <Trigger Property="IsEnabled" Value="False"/>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

我希望 {Binding StringFormat={}, Path=Name} 指向按钮的名称,例如“MyButton”、“MyButton2”等

当我运行此代码时,我收到错误消息“无法冻结此 Storyboard 时间线树以供跨线程使用。” :/ 我知道这是因为我在情节提要中使用了绑定,对吗?我不知道该怎么做才能完成这项工作。

此外,我还想将图像的 ToggleVisibility 设为模板,它接受一次“可见”和一次“隐藏”值。 提前致谢!

【问题讨论】:

    标签: c# .net wpf xaml code-reuse


    【解决方案1】:

    您也可以在样式中定义除模板以外的属性。

        <Style TargetType="{x:Type Button}"
               x:Key="ButtonTemplate">
            <Setter Property="Cursor" Value="Hand" />
            <Setter Property="HorizontalAlignment" Value="Left" />
            <Setter Property="Margin" Value="0,0,0,0" />
            <Setter Property="Width" Value="286" />
            <Setter Property="Focusable" Value="False" />
            <Setter Property="IsTabStop" Value="False" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Button}">
                        ...
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    

    这让你的代码看起来像

        <Button x:Name="MyButton" Style="{StaticResource ButtonTemplate}" Content="hi!" />
        <Button x:Name="MyButton2" Style="{StaticResource ButtonTemplate}" Content="hi 2!" />
    

    【讨论】:

    • 嗨,谢谢您的回复,但这不起作用...我仍然得到相同的 {"Cannot freeze this Storyboard timeline tree for use across threads."} 异常。
    • 好的,这行是什么意思:
    【解决方案2】:

    是的,创建一个目标类型为按钮的样式就可以了。

    Tip:在代码的资源部分下编写所有样式信息(例如边框、背景、模板等)并将它们应用于控件始终是一个好习惯。它将提供良好的可读性。

    HTH :)

    【讨论】:

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