Wpf 如何使listboxitem在选择时展开?
我希望用户按照特定顺序进行选择(首先我希望用户选择数据库,然后我希望他告诉我他的凭据) 为了做到这一点,我向自己提出了一个挑战:制作一个列表框,在选择时扩展项目。 要让它扩展并不困难(比如Wpf 如何使listboxitem在选择时展开?,wpf,animation,listbox,wpf-controls,transition,Wpf,Animation,Listbox,Wpf Controls,Transition,我希望用户按照特定顺序进行选择(首先我希望用户选择数据库,然后我希望他告诉我他的凭据) 为了做到这一点,我向自己提出了一个挑战:制作一个列表框,在选择时扩展项目。 要让它扩展并不困难(比如 Visibility="{Binding Path=IsSelected , RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}} , Converte
Visibility="{Binding Path=IsSelected
, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}
, Converter={StaticResource VisibilityOfBool}
, ConverterParameter=False}"
会成功的)
问题是这种转变是瞬时的;用户很难看到发生了什么。我想做的是一个隐藏面板的动画扩展
这里有一个页面来演示我的意思:
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:system="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
Title="SlidingExpansionOnSelected">
<!--x:Class="TorsSandBox.Pages.SlidingExpansionOnSelected"-->
<Page.Resources>
<DataTemplate x:Key="daItemTemplate">
<StackPanel Margin="10">
<StackPanel.Triggers>
<EventTrigger RoutedEvent="ListBoxItem.Selected">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="daTransform"
Storyboard.TargetProperty="ScaleY"
To="1.0" Duration="0:0:1"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="ListBoxItem.Unselected">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="daTransform"
Storyboard.TargetProperty="ScaleY"
To="0" Duration="0:0:1"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</StackPanel.Triggers>
<TextBlock x:Name="Header" Text="{Binding}"/>
<Border x:Name="daBorder"
BorderThickness="3" BorderBrush="DarkOrange" CornerRadius="5"
HorizontalAlignment="Stretch"
Margin="20 10 10 10"
MinHeight="100"
>
<Border.LayoutTransform>
<ScaleTransform x:Name="daTransform" ScaleX="1" ScaleY="0"/>
</Border.LayoutTransform>
<TextBlock Text="Hide this until selected"
HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
</StackPanel>
</DataTemplate>
</Page.Resources>
<ListBox
HorizontalContentAlignment="Stretch"
ItemTemplate="{StaticResource daItemTemplate}"
>
<system:String>First row</system:String>
<system:String>Second row</system:String>
<system:String>Third row</system:String>
<system:String>Last row</system:String>
</ListBox>
</Page>
第一排
第二排
第三排
最后一排
触发器不起作用,但那是因为我不能让它们开火……有人知道如何做到这一点吗
问候
Tor Thorbergsen事件不需要ListBoxItem前缀,只需使用“已选择”和“未选择” 另一种尝试方法是属性触发器:
这东西太复杂了……
您的方法的错误在于,动画只影响VisualTree上较低的元素,这意味着就我所知,容器不受影响。
我说,在动画中指定属性路径是一个很大的难题。我无法访问StackPanel内部的边框,因为它的Children属性不是依赖属性,而且整个语法非常不寻常。
无论如何,这里有一个黑客解决方案,它是有效的:
<Style TargetType="ListBoxItem">
<Style.Resources>
<Storyboard x:Key="OnSelected1"/>
</Style.Resources>
<Setter Property="Tag">
<Setter.Value>
<sys:Double>0</sys:Double>
</Setter.Value>
</Setter>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel x:Name="stackPanel" Margin="10">
<TextBlock x:Name="Header" Text="{Binding}"/>
<Border x:Name="daBorder"
BorderThickness="3" BorderBrush="DarkOrange" CornerRadius="5"
HorizontalAlignment="Stretch"
Margin="20 10 10 10"
MinHeight="100">
<Border.LayoutTransform>
<ScaleTransform ScaleX="1" ScaleY="{Binding RelativeSource={RelativeSource AncestorType=ListBoxItem}, Path=Tag}"/>
</Border.LayoutTransform>
<TextBlock Text="Hide this until selected" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<EventTrigger RoutedEvent="ListBoxItem.Selected">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="(ListBoxItem.Tag)"
Storyboard.TargetName="{x:Null}"
To="1.0" Duration="0:0:1"/>
</Storyboard>
</BeginStoryboard>
<BeginStoryboard Storyboard="{StaticResource OnSelected1}"/>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="ListBoxItem.Unselected">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="(ListBoxItem.Tag)"
Storyboard.TargetName="{x:Null}"
To="0" Duration="0:0:1"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
0
我试图提取ScaleTransform并在动画和边框中引用它,但无论出于何种原因,都没有成功。编辑:
好的,我已经弄明白了。我已经为此创建了一个附加属性(而不是使用标记)
公共静态类ListBoxHelper
{
公共静态只读从属属性ScaleYAnimationProperty=
DependencyProperty.RegisterAttached(“ScaleYAnimation”、typeof(double)、typeof(ListBoxHelper)、new FrameworkPropertyMetadata(0d));
公共静态双GetScaleYAnimation(UIElement元素)
{
return(double)element.GetValue(ScaleYAnimationProperty);
}
公共静态void SetScaleYAnimation(UIElement元素,双值)
{
SetValue(ScaleYAnimationProperty,value);
}
}
public static class ListBoxHelper
{
public static readonly DependencyProperty ScaleYAnimationProperty =
DependencyProperty.RegisterAttached("ScaleYAnimation", typeof(double), typeof(ListBoxHelper), new FrameworkPropertyMetadata(0d));
public static double GetScaleYAnimation(UIElement element)
{
return (double)element.GetValue(ScaleYAnimationProperty);
}
public static void SetScaleYAnimation(UIElement element, double value)
{
element.SetValue(ScaleYAnimationProperty, value);
}
}
<ListBox ItemsSource="{Binding Contacts}" HorizontalContentAlignment="Stretch">
<ListBox.Resources>
<Style TargetType="ListBoxItem" BasedOn="{StaticResource {x:Type ListBoxItem}}">
<Setter Property="controls:ListBoxHelper.ScaleYAnimation" Value="0"/>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<controls:CircleContentControl Grid.Column="0" Width="40" Height="40">
<Image Source="{Binding Image}"/>
</controls:CircleContentControl>
<TextBlock Text="{Binding FullName}" Grid.Column="1" Margin="10,0,5,0" VerticalAlignment="Center"/>
<TextBlock Text="{Binding PhoneNumber}" Grid.Column="2" VerticalAlignment="Center" FontStyle="Italic">
<TextBlock.LayoutTransform>
<ScaleTransform ScaleX="0.7" ScaleY="0.7"/>
</TextBlock.LayoutTransform>
</TextBlock>
<StackPanel Orientation="Horizontal" Grid.Column="3" VerticalAlignment="Center" HorizontalAlignment="Center">
<Button cal:Message.Attach="Call($dataContext)" Width="30" Height="30" Style="{StaticResource ContactDialButtonStyle}">
<Rectangle Width="10" Height="10" Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}">
<Rectangle.OpacityMask>
<VisualBrush Stretch="Fill" Visual="{DynamicResource appbar_phone}" />
</Rectangle.OpacityMask>
</Rectangle>
</Button>
</StackPanel>
</Grid>
<Border x:Name="daBorder"
BorderThickness="3" BorderBrush="DarkOrange" CornerRadius="5"
HorizontalAlignment="Stretch"
Margin="20 10 10 10"
MinHeight="100">
<Border.LayoutTransform>
<ScaleTransform ScaleX="1" ScaleY="{Binding RelativeSource={RelativeSource AncestorType=ListBoxItem}, Path=(controls:ListBoxHelper.ScaleYAnimation)}"/>
</Border.LayoutTransform>
<TextBlock Text="Hide this until selected" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<EventTrigger RoutedEvent="ListBoxItem.Selected">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="(controls:ListBoxHelper.ScaleYAnimation)"
Storyboard.TargetName="{x:Null}"
To="1.0" Duration="0:0:1"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="ListBoxItem.Unselected">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="(controls:ListBoxHelper.ScaleYAnimation)"
Storyboard.TargetName="{x:Null}"
To="0.0" Duration="0:0:1"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
</ListBox.Resources>
</ListBox>
System.Windows.Data Error: 23 : Cannot convert '<null>' from type '<null>' to type 'System.Double' for 'en-US' culture with default conversions; consider using Converter property of Binding. NotSupportedException:'System.NotSupportedException: DoubleConverter não pode ser convertido de (nulo).
em System.ComponentModel.TypeConverter.GetConvertFromException(Object value)
em System.ComponentModel.TypeConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
em System.ComponentModel.BaseNumberConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
em MS.Internal.Data.DefaultValueConverter.ConvertHelper(Object o, Type destinationType, DependencyObject targetElement, CultureInfo culture, Boolean isForward)'
System.Windows.Data Error: 6 : 'ObjectSourceConverter' converter failed to convert value '<null>' (type '<null>'); fallback value will be used, if available. BindingExpression:Path=Tag; DataItem='ListBoxItem' (Name=''); target element is 'ScaleTransform' (HashCode=48000142); target property is 'ScaleY' (type 'Double') NotSupportedException:'System.NotSupportedException: DoubleConverter não pode ser convertido de (nulo).
em MS.Internal.Data.DefaultValueConverter.ConvertHelper(Object o, Type destinationType, DependencyObject targetElement, CultureInfo culture, Boolean isForward)
em MS.Internal.Data.ObjectSourceConverter.Convert(Object o, Type type, Object parameter, CultureInfo culture)
em System.Windows.Data.BindingExpression.ConvertHelper(IValueConverter converter, Object value, Type targetType, Object parameter, CultureInfo culture)'