我想实现特殊按钮,我什至不知道如何开始。
我希望我Button
的内容属性是:Play
。单击它时,我希望Buttons
在左侧和右侧弹出另外 2 个:Single Play
和Parallel Play
我想实现特殊按钮,我什至不知道如何开始。
我希望我Button
的内容属性是:Play
。单击它时,我希望Buttons
在左侧和右侧弹出另外 2 个:Single Play
和Parallel Play
您所要做的就是创建您的 3 个按钮,然后在您的 2 个侧面按钮上放置一个可见性转换器。创建一个属性,如果它们应该可见或不可见,并将可见性转换器绑定到此属性。单击该Play
按钮时应修改此属性。
我希望这能给你一个关于如何开始的想法。
经过大量讨论,这是解决此问题的结果:
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;
}
}
}