WPF:如何实现一个按钮,使其他2个按钮可见,并带有淡入淡出效果

时间:2015-06-10 14:02:31

标签: wpf split-button

我想实现特殊按钮,我甚至不知道如何从这开始。

我希望Button的内容属性为:Play。点击它时,我想在左侧和右侧弹出另外两个ButtonsSingle PlayParallel Play

2 个答案:

答案 0 :(得分:2)

您所要做的就是创建3个按钮,然后在两侧按钮上放置一个可见性转换器。创建一个属性,如果它们应该可见,它们将保持并将可见性转换器绑定到此属性。单击时,Play按钮应修改此属性。

我希望这可以让您了解如何从此开始。

答案 1 :(得分:1)

经过大量讨论,以下是解决此问题的结果:

XAML:

<Window x:Class="WpfApplication3.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:my="clr-namespace:WpfApplication3"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <StackPanel Orientation="Horizontal">
        <Button Name="btnSinglePlay" Visibility="Collapsed" my:VisibilityAnimation.IsActive="True">SinglePlay</Button>
        <Button Name="btnPlay" Click="btnPlay_Click">Play</Button>
        <Button Name="btnParallelPlay" Visibility="Collapsed" my:VisibilityAnimation.IsActive="True">ParallelPlay</Button>
    </StackPanel>
</Grid>

C#设置双面按钮可见。

private void btnPlay_Click(object sender, RoutedEventArgs e)
        {
            btnSinglePlay.Visibility = Visibility.Visible;
            btnParallelPlay.Visibility = Visibility.Visible;
        }

允许淡入/淡出的c#代码。它来自WPF Fade Animation所以支持Anvaka而不是我。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media.Animation;

namespace WpfApplication3
{
    public class VisibilityAnimation : DependencyObject
    {
        private const int DURATION_MS = 200;

        private static readonly Hashtable _hookedElements = new Hashtable();

        public static readonly DependencyProperty IsActiveProperty =
          DependencyProperty.RegisterAttached("IsActive",
          typeof(bool),
          typeof(VisibilityAnimation),
          new FrameworkPropertyMetadata(false, new PropertyChangedCallback(OnIsActivePropertyChanged)));

        public static bool GetIsActive(UIElement element)
        {
            if (element == null)
            {
                throw new ArgumentNullException("element");
            }

            return (bool)element.GetValue(IsActiveProperty);
        }

        public static void SetIsActive(UIElement element, bool value)
        {
            if (element == null)
            {
                throw new ArgumentNullException("element");
            }
            element.SetValue(IsActiveProperty, value);
        }

        static VisibilityAnimation()
        {
            UIElement.VisibilityProperty.AddOwner(typeof(FrameworkElement),
                                                  new FrameworkPropertyMetadata(Visibility.Visible, new PropertyChangedCallback(VisibilityChanged), CoerceVisibility));
        }

        private static void VisibilityChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            // So what? Ignore.
        }

        private static void OnIsActivePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var fe = d as FrameworkElement;
            if (fe == null)
            {
                return;
            }
            if (GetIsActive(fe))
            {
                HookVisibilityChanges(fe);
            }
            else
            {
                UnHookVisibilityChanges(fe);
            }
        }

        private static void UnHookVisibilityChanges(FrameworkElement fe)
        {
            if (_hookedElements.Contains(fe))
            {
                _hookedElements.Remove(fe);
            }
        }

        private static void HookVisibilityChanges(FrameworkElement fe)
        {
            _hookedElements.Add(fe, false);
        }

        private static object CoerceVisibility(DependencyObject d, object baseValue)
        {
            var fe = d as FrameworkElement;
            if (fe == null)
            {
                return baseValue;
            }

            if (CheckAndUpdateAnimationStartedFlag(fe))
            {
                return baseValue;
            }
            // If we get here, it means we have to start fade in or fade out
            // animation. In any case return value of this method will be
            // Visibility.Visible. 

            var visibility = (Visibility)baseValue;

            var da = new DoubleAnimation
            {
                Duration = new Duration(TimeSpan.FromMilliseconds(DURATION_MS))
            };

            da.Completed += (o, e) =>
            {
                // This will trigger value coercion again
                // but CheckAndUpdateAnimationStartedFlag() function will reture true
                // this time, and animation will not be triggered.
                fe.Visibility = visibility;
                // NB: Small problem here. This may and probably will brake 
                // binding to visibility property.
            };

            if (visibility == Visibility.Collapsed || visibility == Visibility.Hidden)
            {
                da.From = 1.0;
                da.To = 0.0;
            }
            else
            {
                da.From = 0.0;
                da.To = 1.0;
            }

            fe.BeginAnimation(UIElement.OpacityProperty, da);
            return Visibility.Visible;
        }

        private static bool CheckAndUpdateAnimationStartedFlag(FrameworkElement fe)
        {
            var hookedElement = _hookedElements.Contains(fe);
            if (!hookedElement)
            {
                return true; // don't need to animate unhooked elements.
            }

            var animationStarted = (bool)_hookedElements[fe];
            _hookedElements[fe] = !animationStarted;

            return animationStarted;
        }
    }
}