2016-08-01 113 views
2

由於其他原因,我需要WPF CustomControl。我的目標是幻燈片窗口,有財產IsActiveCustomControl滑動窗口

如果此屬性更改爲true,則幻燈片窗口將從左向右滑動。如果此屬性從true改回,那麼SlideWindow會滑出。

此功能正常工作(我通過觸發器XAML文件)。我還需要設置知名度Visibile(滑動效果開始前)或摺疊(滑出效果完成後)。這就是問題所在。


SlideWindowControl.cs

using System; 
using System.Windows; 
using System.Windows.Controls; 

namespace SlideWindowTest 
{ 
    public class SlideWindowControl : ContentControl 
    { 
     public static readonly DependencyProperty IsActiveProperty = DependencyProperty.Register(
      "IsActive", typeof(Boolean), typeof(SlideWindowControl), new PropertyMetadata(true)); 

     static SlideWindowControl() 
     { 
      DefaultStyleKeyProperty.OverrideMetadata(typeof(SlideWindowControl), new FrameworkPropertyMetadata(typeof(SlideWindowControl))); 
     } 

     public Boolean IsActive 
     { 
      get { return (Boolean)GetValue(IsActiveProperty); } 
      set { SetValue(IsActiveProperty, value); } 
     } 
    } 
} 

通訊Generic.xamlSlideWindowControl

<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:SlideWindowTest"> 

    <Style TargetType="{x:Type local:SlideWindowControl}"> 
     <Setter Property="RenderTransform"> 
      <Setter.Value> 
       <ScaleTransform ScaleX="1"/> 
      </Setter.Value> 
     </Setter> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type local:SlideWindowControl}"> 
        <Border Background="{TemplateBinding Background}" 
          BorderBrush="{TemplateBinding BorderBrush}" 
          BorderThickness="{TemplateBinding BorderThickness}" 
          x:Name="Root"> 
         <StackPanel Orientation="Vertical"> 
          <Grid Background="Black"> 
           <TextBlock Text="HEADER" Foreground="White" Margin="17" FontSize="20pt" /> 
          </Grid> 
          <ContentPresenter /> 
         </StackPanel> 
        </Border> 

        <ControlTemplate.Triggers> 
         <Trigger Property="IsActive" Value="True"> 

          <!-- Show --> 
          <Trigger.EnterActions> 
           <BeginStoryboard> 
            <Storyboard> 
             <!-- Visibility change cause trouble 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Duration="0" BeginTime="0"> 
              <DiscreteObjectKeyFrame Value="{x:Static Visibility.Visible}" /> 
             </ObjectAnimationUsingKeyFrames> 
             --> 

             <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleX" From="0" Duration="0:00:00.5" /> 
            </Storyboard> 
           </BeginStoryboard> 
          </Trigger.EnterActions> 

          <!-- Hide --> 
          <Trigger.ExitActions> 
           <BeginStoryboard> 
            <Storyboard> 
             <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleX" From="1" To="0" Duration="0:00:00.5"/> 

             <!-- Visibility change cause trouble 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Duration="0" BeginTime="0:00:00.5"> 
              <DiscreteObjectKeyFrame Value="{x:Static Visibility.Collapsed}" /> 
             </ObjectAnimationUsingKeyFrames> 
             --> 
            </Storyboard> 
           </BeginStoryboard> 
          </Trigger.ExitActions> 
         </Trigger> 
        </ControlTemplate.Triggers> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</ResourceDictionary> 

SlideWindowControl在 使用

例MainWindow.xaml

<Window x:Class="SlideWindowTest.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:SlideWindowTest" 
     Title="MainWindow" Height="350" Width="525"> 
    <StackPanel Orientation="Vertical"> 
     <StackPanel Orientation="Horizontal"> 
      <Button Content="Slide In" Click="SlideInButton_Click"/> <!-- InMainWindow.xaml.cs set MySlideWindow.IsActive = true; --> 
      <Button Content="Slide Out" Click="SlideOutButton_Click" /> <!-- InMainWindow.xaml.cs set MySlideWindow.IsActive = false; --> 
     </StackPanel> 

     <local:SlideWindowControl x:Name="MySlideWindow"> 
      <TextBlock FontSize="40pt">Super Content!</TextBlock> 
     </local:SlideWindowControl> 
    </StackPanel> 
</Window> 

我嘗試在Generic.xaml設置visibility屬性也觸發了SlideWindowControl(見註釋代碼請),但它會中斷整個觸發器(不顯示動畫效果)。

如何才能實現可見性屬性的更改?我需要在其他組件中綁定到可見性屬性

回答

1

的溶液可以是:

  1. 創建兩個故事板作爲靜態資源和在BeginStoryboard-故事板({StaticResource的}的slideIn)引用它們而不是讓它們爲內聯的兒童。

  2. 實施其已完成事件

  3. 在完成-事件處理程序設置能見度倒塌時IsActive =假。
  4. 在FadeIn-click事件中,在設置IsActive = true之前,必須將Visibility設置爲Visible。

這有點不對稱,但它適用於我的測試案例。

<Window x:Class="SO38699140.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:local="clr-namespace:SO38699140" 
     mc:Ignorable="d" 
     Title="MainWindow" Height="350" Width="525"> 
    <Window.Resources> 

    <Storyboard x:Key="SlideIn" Completed="Storyboard_Completed" > 
     <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleX" From="0" Duration="0:00:00.5" /> 
    </Storyboard> 

    <Storyboard x:Key="SlideOut" Completed="Storyboard_Completed"> 
     <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleX" From="1" To="0" Duration="0:00:00.5" /> 
    </Storyboard> 


    <Style TargetType="{x:Type local:SlideWindowControl}"> 
     <Setter Property="RenderTransform"> 
     <Setter.Value> 
      <ScaleTransform ScaleX="1"/> 
     </Setter.Value> 
     </Setter> 
     <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type local:SlideWindowControl}"> 
      <Border Background="{TemplateBinding Background}" 
          BorderBrush="{TemplateBinding BorderBrush}" 
          BorderThickness="{TemplateBinding BorderThickness}" 
          x:Name="Root"> 
       <StackPanel Orientation="Vertical"> 
       <Grid Background="Black"> 
        <TextBlock Text="HEADER" Foreground="White" Margin="17" FontSize="20pt" /> 
       </Grid> 
       <ContentPresenter /> 
       </StackPanel> 
      </Border> 

      <ControlTemplate.Triggers> 
       <Trigger Property="IsActive" Value="True"> 

       <!-- Show --> 
       <Trigger.EnterActions> 
        <BeginStoryboard Storyboard="{StaticResource SlideIn}"> 
        </BeginStoryboard> 
       </Trigger.EnterActions> 

       <!-- Hide --> 
       <Trigger.ExitActions> 
        <BeginStoryboard Storyboard="{StaticResource SlideOut}"> 
        </BeginStoryboard> 
       </Trigger.ExitActions> 
       </Trigger> 
      </ControlTemplate.Triggers> 
      </ControlTemplate> 
     </Setter.Value> 
     </Setter> 
    </Style> 
    </Window.Resources> 
    <StackPanel Orientation="Vertical"> 
     <StackPanel Orientation="Horizontal"> 
     <Button Content="Slide In" Click="SlideInButton_Click"/> 
     <!-- InMainWindow.xaml.cs set MySlideWindow.IsActive = true; --> 
     <Button Content="Slide Out" Click="SlideOutButton_Click" /> 
     <!-- InMainWindow.xaml.cs set MySlideWindow.IsActive = false; --> 
     <TextBlock Text="{Binding ElementName=MySlideWindow, Path=Visibility}" /> 

    </StackPanel> 

     <local:SlideWindowControl x:Name="MySlideWindow"> 
     <TextBlock FontSize="40pt">Super Content!</TextBlock> 
     </local:SlideWindowControl> 
    </StackPanel> 
</Window> 

     } 

    private void SlideInButton_Click(object sender, RoutedEventArgs e) 
    { 
     MySlideWindow.Visibility = Visibility.Visible; 
     MySlideWindow.IsActive = true; 
    } 

    private void SlideOutButton_Click(object sender, RoutedEventArgs e) 
    { 
     MySlideWindow.IsActive = false; 
    } 

    private void Storyboard_Completed(object sender, EventArgs e) 
    { 
     if (!MySlideWindow.IsActive) 
     MySlideWindow.Visibility = Visibility.Collapsed; 

    }