1

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

我希望我Button的内容属性是:Play。单击它时,我希望Buttons在左侧和右侧弹出另外 2 个:Single PlayParallel Play

4

2 回答 2

2

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

我希望这能给你一个关于如何开始的想法。

于 2015-06-10T14:13:51.230 回答
1

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

xml:

<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# 设置 2 侧按钮可见。

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;
        }
    }
}
于 2015-06-10T20:49:33.290 回答