【问题标题】:How to write a style for a control that changes width of another control?如何为更改另一个控件宽度的控件编写样式?
【发布时间】:2013-10-05 06:40:26
【问题描述】:

有没有办法为一个改变另一个控件宽度的控件编写Style

<Style x:Key="SubMenuStyle" TargetType="Label">
    <Setter Property="HorizontalContentAlignment" Value="Center"/>
    <Setter Property="FontFamily" Value="Arial"/>
    <Setter Property="FontSize" Value="14"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="BorderBrush" Value="LightCyan"/>

    <Style.Triggers>
        <EventTrigger RoutedEvent="MouseLeftButtonDown">
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimation Storyboard.TargetName="Menu" Storyboard.TargetProperty="Width" To="0" Duration="0:0:.5"/>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Style.Triggers>
</Style>

此代码导致错误:

无法在样式设置器上设置 TargetName 属性

我知道我可以在下面编写代码并且它可以工作:

<Label Name="Owners" Margin="0,1,0,0" MouseLeftButtonDown="SubMenuClicked" Style="{StaticResource SubMenuStyle}">
    <Label.Triggers>
        <EventTrigger RoutedEvent="MouseLeftButtonDown">
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimation Storyboard.TargetName="Menu" Storyboard.TargetProperty="Width" To="0" Duration="0:0:.5"/>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Label.Triggers>
</Label>

但由于我在多个标签中使用此触发器,所以我想以一种样式编写一次。

这是我定义控件的代码:

<Border Name="Menu" Grid.Column="2" Grid.Row="1" Width="0" HorizontalAlignment="Right" BorderBrush="LightBlue" BorderThickness="2" CornerRadius="2" Background="LightCyan">
    <StackPanel Name="MenuPanel">
        <Button Style="{StaticResource MenuButtonsStyle}">
            <Button.Triggers>
                <EventTrigger RoutedEvent="Button.Click">
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation Storyboard.TargetName="ListsMenu" Storyboard.TargetProperty="Height" To="86" Duration="0:0:.6"/>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </Button.Triggers>
        </Button>

        <StackPanel Name="ListsMenu" Height="0">
            <Label Name="Owners" Margin="0,1,0,0" MouseLeftButtonDown="SubMenuClicked" Style="{StaticResource SubMenuStyle}"/>
            <Label Name="Contacts" MouseLeftButtonDown="SubMenuClicked" Style="{StaticResource SubMenuStyle}"/>
            <Label Name="Groups" MouseLeftButtonDown="SubMenuClicked" Style="{StaticResource SubMenuStyle}"/>
        </StackPanel>
    </StackPanel>
</Border>

场景:有一个边框,它的默认宽度为零,它会在另一个可以正常工作的触发器中升至 165,我想在单击标签时再次将其动画为零,但我无法访问该宽度标签样式的边框

【问题讨论】:

  • Style的触发器中不能使用带有TargetName的对象,这样的动画。为此,它们被放置在触发器模板中。 (Link)。作为替代方案,您可以使用DataTemplate,因为他确实有一个名称范围。只需将这些对象放在DataTemplate 中。 Example 使用 DataTemplate.
  • 一个数据模板?!还是控制模板?我看了一下链接,但它是关于一个名为 River 的类,虽然我没有这样的数据类,但我只有一个边框和一些按钮和标签。不过谢谢你的回答,我去看看 controltemplates

标签: wpf xaml


【解决方案1】:

您声称您在多个标签中使用触发器,因此您可以像这样定义一次触发器

        <Storyboard x:Key="animation">
             <DoubleAnimation Storyboard.TargetName="ListsMenu" Storyboard.TargetProperty="Height" To="86" Duration="0:0:.6"/>
        </Storyboard>

以后需要的时候可以调用它

 <EventTrigger RoutedEvent="MouseEnter" >
                <BeginStoryboard Storyboard="{StaticResource animation}"/> 
            </EventTrigger>

但我有点困惑你想要获得什么。 正如所说,您无法访问样式,因为样式没有名称范围。如果它改变标签的宽度,你可以这样做

  <Style x:Key="style_button" TargetType="Button">
        <Style.Triggers>
            <EventTrigger RoutedEvent="MouseEnter">
                <BeginStoryboard>
                    <Storyboard>
                        <DoubleAnimation Storyboard.TargetProperty="Width" To="300" />
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
        </Style.Triggers>
    </Style>

但它通过 StoryBoard.TargetName 调用另一个对象。

【讨论】:

  • 有一个边框,它的默认宽度为零,它会在另一个可以正常工作的触发器中升至 165,我想在单击标签时再次将其动画为零,但我无法访问标签样式中该边框的宽度。但是,您当前的答案似乎不错,至少它可以防止重复代码。
  • 我试过了,效果很好,但这是否意味着没有办法做到风格?或类似的东西?
【解决方案2】:

尝试:

 <EventTrigger RoutedEvent="MouseLeftButtonDown">
     <BeginStoryboard>
           <Storyboard>
               <DoubleAnimation Storyboard.Target="{Binding ElementName=Menu}"
                                Storyboard.TargetProperty="Width" To="0" Duration="0:0:.5"/>
           </Storyboard>
      </BeginStoryboard>
  </EventTrigger>

TargetName 仅在模板内有效。

【讨论】:

  • 感谢您的回答,但它不起作用,它会抛出一个异常,当 Width 未设置为一个值并且它是 Nan,但我将 Width 设置为零时发生!
  • PresentationCore.dll 中出现“System.Windows.Media.Animation.AnimationException”类型的未处理异常附加信息:无法为“System.Windows.Controls.Label”上的“Width”属性设置动画使用“System.Windows.Media.Animation.DoubleAnimation”。有关详细信息,请参阅内部异常。 -------------------------------------- 异常:抛出:“,System.Widow.Media。 DoubleAnimation' 不能使用默认值 'NaN'"(System.InvalidOperationException)
  • @SamanHakimzadehAbyaneh 为什么将您的标签称为“菜单”?
  • 我不是指标签!触发器必须将称为菜单的边框的宽度更改为零,它的默认值是零,但是在另一个可以正常工作的触发器中它将更改为 165,然后在我单击标签后,我希望它再次更改为零
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多