템플릿 컨트롤을 만들고 있습니다. 확장 된 컨트롤을 만드는 것이 아이디어입니다. ContentPresenter
에 각각 해당하는 Header 및 Details 속성을 갖습니다. 사용자는 헤더를 탭 할 수 있으며 세부 정보 섹션은 애니메이션으로 확장됩니다. 사용자가 헤더를 다시 탭하면 세부 정보 섹션이 다른 애니메이션과 함께 취소됩니다.템플릿 컨트롤에서 작동하도록 VisualStateGroup.Transitions을 가져올 수 없습니다.
저는 Visual States와 VisualTransitions
을 사용하고 있습니다. 여기 내 코드가있다.
[TemplatePart(Name ="Header", Type=typeof(ContentPresenter))]
[TemplatePart(Name = "Details", Type = typeof(ContentPresenter))]
[TemplateVisualState(GroupName ="ExpandStates",Name ="Expanded")]
[TemplateVisualState(GroupName = "ExpandStates", Name = "Compact")]
public sealed class ExpandingItem : Control
{
private ContentPresenter header;
private bool isExpanded;
public ExpandingItem()
{
this.DefaultStyleKey = typeof(ExpandingItem);
}
public FrameworkElement Header
{
get { return (FrameworkElement)GetValue(HeaderProperty); }
set { SetValue(HeaderProperty, value); }
}
// Using a DependencyProperty as the backing store for Header. This enables animation, styling, binding, etc...
public static readonly DependencyProperty HeaderProperty =
DependencyProperty.Register("Header", typeof(FrameworkElement), typeof(ExpandingItem), new PropertyMetadata(default(FrameworkElement)));
public FrameworkElement Details
{
get { return (FrameworkElement)GetValue(DetailsProperty); }
set { SetValue(DetailsProperty, value); }
}
// Using a DependencyProperty as the backing store for Details. This enables animation, styling, binding, etc...
public static readonly DependencyProperty DetailsProperty =
DependencyProperty.Register("Details", typeof(FrameworkElement), typeof(ExpandingItem), new PropertyMetadata(default(FrameworkElement)));
protected override void OnApplyTemplate()
{
if (header != null)
{
header.Tapped -= HeaderTapped;
}
base.OnApplyTemplate();
header = (ContentPresenter)GetTemplateChild("Header");
header.Tapped += HeaderTapped;
}
private void HeaderTapped(object sender, TappedRoutedEventArgs e)
{
if (isExpanded)
{
Retract();
OnStateChanged(new ExpandItemEventArgs(false));
}
else
{
Expand();
OnStateChanged(new ExpandItemEventArgs(true));
}
isExpanded = !isExpanded;
}
public void Expand()
{
VisualStateManager.GoToState(this, "Expanded", true);
}
public void Retract()
{
VisualStateManager.GoToState(this, "Compact", true);
}
public EventHandler<ExpandItemEventArgs> StateChanged;
private void OnStateChanged(ExpandItemEventArgs e)
{
// Make a temporary copy of the event to avoid possibility of
// a race condition if the last subscriber unsubscribes
// immediately after the null check and before the event is raised.
EventHandler<ExpandItemEventArgs> handler = StateChanged;
// Event will be null if there are no subscribers
if (handler != null)
{
handler(this, e);
}
}
}
그리고 템플릿
<Style TargetType="controls:ExpandingItem" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:ExpandingItem">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ExpandStates">
<VisualStateGroup.Transitions>
<VisualTransition From="Compact" To="Expanded">
<VisualTransition.Storyboard>
<Storyboard>
<FadeInThemeAnimation
TargetName="Details"/>
</Storyboard>
</VisualTransition.Storyboard>
</VisualTransition>
<VisualTransition From="Expanded" To="Compact">
<VisualTransition.Storyboard>
<Storyboard>
<FadeOutThemeAnimation
TargetName="Details"/>
</Storyboard>
</VisualTransition.Storyboard>
</VisualTransition>
</VisualStateGroup.Transitions>
<VisualState x:Name="Compact"/>
<VisualState x:Name="Expanded">
<VisualState.Setters>
<Setter Target="Details.Visibility" Value="Visible"/>
</VisualState.Setters>
<Storyboard>
<FadeInThemeAnimation
TargetName="Details"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter
x:Name="Header"
Grid.Row="0"
Content="{TemplateBinding Header}"/>
<ContentPresenter
x:Name="Details"
Grid.Row="1"
Content="{TemplateBinding Details}"
Visibility="Collapsed"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
는 간단한 애니메이션이기 때문에 나는 fadein/페이드 아웃 애니메이션을 사용하고 있지만, 이상적으로 나는 splitopen/splitclose 애니메이션 같은 것을 사용하고 싶습니다.
상태 사이의 전환이 정상적으로 발생하더라도 문제가 있습니다. 애니메이션은 결코 발생하지 않습니다. 문제를 파악하도록 도와 줄 수 있습니까?
편집 : 여기에 문제는 상태 사이의 전환이 일반적으로 발생에도 불구하고 있다는 것입니다 ExpandItemEventArgs
public class ExpandItemEventArgs : EventArgs
{
private readonly bool isExpanded;
public ExpandItemEventArgs(bool isExpanded)
{
this.isExpanded = isExpanded;
}
public bool IsExpanded => isExpanded;
}
은 어떻게'ExpandItemEv입니다 entArgs'? 이 코드를 게시 할 수 있습니까? –
@ GraceFeng-MSFT ExpandItemEventArgs를 추가했습니다. 나는 그들이 시각적 인 상태 변화에 영향을 줄 수 있다고 생각하지 않는다. – Corcus