- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我是 WPF 和 C# 开发的新手,我正在制作这个应用程序。我不知道是否有人熟悉 VOIP App Discord,但他们有一个我非常喜欢的特定行为,并想尝试用 WPF 创建类似的风格。
当您在 Discord 上添加服务器时,您单击一个按钮,整个后窗消失,一个新窗口在前台打开,提示您添加服务器。在窗口外单击会导致窗口在背景窗口处关闭以重新聚焦。
无论如何,这是一个GIF以帮助证明这种特定行为(忽略星星,不想泄露个人信息)。
https://i.imgur.com/cn0sFlO.gifv
我对这一切真的很陌生,所以不知道如何模仿这种行为。
最佳答案
这是一个您可以使用和操作的自定义 Flyout 控件,它的工作方式与您正在寻找的一样。
下面将向您展示如何编写和使用与此类似的自定义 Flyout:
<Window.Resources>
<local:FlyoutControl x:Key="CustomFlyout">
<Grid Width="400" Height="200" Background="PeachPuff">
<TextBlock Text="Inside Flyout" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</local:FlyoutControl>
</Window.Resources>
<Grid>
<Button Content="I have a flyout"
Width="120"
Height="40"
local:FlyoutAttach.Flyout="{StaticResource CustomFlyout}"/>
</Grid>
我看到您已经有了答案,但是当我看到这个问题时我就开始构建它了,所以如果您想接受它并按照您希望的方式使用它,那很好;我想我也会分享这个答案,因为我付出了努力。
我建议更进一步,添加一个 AttachableProperty,可用于将 Flyout 附加到控件,就像 UWP 应用程序中的按钮一样。在 AP 中,您可以找到 MainWindow 并将其添加到网格的底部并自动显示;然而,这假设 MainWindow 有一个 Grid 的根面板。编辑:我还添加了一个附加属性以供引用。
FlyoutControl.xaml
<ContentControl x:Name="ContentControl"
x:Class="Question_Answer_WPF_App.FlyoutControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Template="{DynamicResource ContentControlTemplate}"
Opacity="0"
Visibility="Hidden">
<ContentControl.Resources>
<Duration x:Key="OpenDuration">00:00:00.4</Duration>
<Storyboard x:Key="OpenStoryboard" Duration="{StaticResource OpenDuration}">
<DoubleAnimation Storyboard.TargetName="ContentControl" Storyboard.TargetProperty="Opacity" To="1" Duration="{StaticResource OpenDuration}">
<DoubleAnimation.EasingFunction>
<BackEase EasingMode="EaseOut" Amplitude="0.4"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentControl" Storyboard.TargetProperty="Visibility" Duration="{StaticResource OpenDuration}">
<DiscreteObjectKeyFrame Value="{x:Static Visibility.Visible}" KeyTime="00:00:00" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="OpenInnerContentStoryboard" Duration="{StaticResource OpenDuration}">
<DoubleAnimation Storyboard.TargetName="scaleTransform" Storyboard.TargetProperty="ScaleX" To="1" Duration="{StaticResource OpenDuration}">
<DoubleAnimation.EasingFunction>
<BackEase EasingMode="EaseOut" Amplitude="0.4"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
<DoubleAnimation Storyboard.TargetName="scaleTransform" Storyboard.TargetProperty="ScaleY" To="1" Duration="{StaticResource OpenDuration}">
<DoubleAnimation.EasingFunction>
<BackEase EasingMode="EaseOut" Amplitude="0.4"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
<Storyboard x:Key="CloseStoryboard">
<DoubleAnimation Storyboard.TargetName="ContentControl" Storyboard.TargetProperty="Opacity" To="0" Duration="00:00:00"/>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentControl" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame Value="{x:Static Visibility.Hidden}" KeyTime="00:00:00" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="CloseInnerContentStoryboard">
<DoubleAnimation Storyboard.TargetName="scaleTransform" Storyboard.TargetProperty="ScaleX" To="0" Duration="00:00:00"/>
<DoubleAnimation Storyboard.TargetName="scaleTransform" Storyboard.TargetProperty="ScaleY" To="0" Duration="00:00:00"/>
</Storyboard>
<ControlTemplate x:Key="InnerContentButtonTemplate" TargetType="Button">
<ContentPresenter />
</ControlTemplate>
<ControlTemplate x:Key="BackgroundButtonTemplate" TargetType="Button">
<Grid Background="Black">
<Button VerticalAlignment="Center" HorizontalAlignment="Center" Click="InnerContentButtonClick" Template="{StaticResource InnerContentButtonTemplate}">
<ContentPresenter />
</Button>
</Grid>
</ControlTemplate>
<ControlTemplate x:Key="ContentControlTemplate" TargetType="ContentControl">
<Button x:Name="BackgroundButton" Template="{StaticResource BackgroundButtonTemplate}" Background="#B2000000" Click="BackgroundButtonClick">
<ContentPresenter RenderTransformOrigin="0.5, 0.5">
<ContentPresenter.RenderTransform>
<ScaleTransform x:Name="scaleTransform" ScaleX="0" ScaleY="0"/>
</ContentPresenter.RenderTransform>
</ContentPresenter>
</Button>
</ControlTemplate>
</ContentControl.Resources>
</ContentControl>
FlyoutControl.xaml.cs
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Animation;
namespace Question_Answer_WPF_App
{
public partial class FlyoutControl : ContentControl
{
public FlyoutControl() => InitializeComponent();
private void OpenFlyout()
{
var openStoryboard = Resources["OpenStoryboard"] as Storyboard;
var openInnerContentStoryboard = Resources["OpenInnerContentStoryboard"] as Storyboard;
openStoryboard.Begin();
openInnerContentStoryboard.Begin(this, Template);
}
private void CloseFlyout()
{
var closeStoryboard = Resources["CloseStoryboard"] as Storyboard;
var closeInnerContentStoryboard = Resources["CloseInnerContentStoryboard"] as Storyboard;
closeStoryboard.Begin();
closeInnerContentStoryboard.Begin(this, Template);
}
public bool IsOpen
{
get { return (bool)GetValue(IsOpenProperty); }
set { SetValue(IsOpenProperty, value); }
}
public static readonly DependencyProperty IsOpenProperty =
DependencyProperty.Register(nameof(IsOpen),
typeof(bool),
typeof(FlyoutControl),
new PropertyMetadata(false,
new PropertyChangedCallback((s, e) =>
{
if (s is FlyoutControl flyoutControl && e.NewValue is bool boolean)
{
if (boolean)
{
flyoutControl.OpenFlyout();
}
else
{
flyoutControl.CloseFlyout();
}
}
})));
//Closes Flyout
private void BackgroundButtonClick(object sender, RoutedEventArgs e) => IsOpen = false;
//Disables clicks from within inner content from explicitly closing Flyout.
private void InnerContentButtonClick(object sender, RoutedEventArgs e) => e.Handled = true;
}
}
可以像这样使用:
<local:FlyoutControl>
<MyUserControlThatLooksLikeDiscord />
</local:FlyoutControl>
您可以手动控制它,也可以像这样通过绑定(bind)控制它:
代码隐藏
flyoutControl.IsOpen = !flyoutControl.IsOpen;
XAML 绑定(bind)
<Grid>
<local:FlyoutControl x:Name="flyoutControl">
<Grid Width="400" Height="200" Background="PeachPuff">
<TextBlock Text="Inside Flyout" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</local:FlyoutControl>
<CheckBox IsChecked="{Binding IsOpen, ElementName=flyoutControl}" Content="Toggle Flyout" Margin="21" VerticalAlignment="Top" HorizontalAlignment="Left"/>
</Grid>
这是可附加属性,因此您可以更像 UWP 应用一样使用它
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
namespace Question_Answer_WPF_App
{
public class FlyoutAttach
{
public static FlyoutControl GetFlyout(ButtonBase button)
=> (FlyoutControl)button.GetValue(FlyoutProperty);
public static void SetFlyout(ButtonBase button, FlyoutControl value)
=> button.SetValue(FlyoutProperty, value);
public static readonly DependencyProperty FlyoutProperty =
DependencyProperty.RegisterAttached("Flyout",
typeof(FlyoutControl),
typeof(FlyoutAttach),
new PropertyMetadata(null,
new PropertyChangedCallback((s, e) =>
{
if (s is ButtonBase button && e.NewValue is FlyoutControl newFlyout)
{
if (Application.Current.MainWindow.Content is Grid grid)
{
if (e.OldValue is FlyoutControl oldFlyout)
{
grid.Children.Remove(oldFlyout);
}
grid.Children.Add(newFlyout);
button.Click -= buttonClick;
button.Click += buttonClick;
}
else
{
throw new Exception($"{nameof(Application.Current.MainWindow)} must have a root layout panel of type {nameof(Grid)} in order to use attachable Flyout.");
}
void buttonClick(object sender, RoutedEventArgs routedEventArgs)
{
newFlyout.IsOpen = true;
}
}
})));
}
}
使用起来就这么简单:
<Window.Resources>
<local:FlyoutControl x:Key="CustomFlyout" x:Name="flyoutControl">
<Grid Width="400" Height="200" Background="PeachPuff">
<TextBlock Text="Inside Flyout" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</local:FlyoutControl>
</Window.Resources>
<Grid>
<Button Content="I have a flyout"
Width="120"
Height="40"
local:FlyoutAttach.Flyout="{StaticResource CustomFlyout}"/>
</Grid>
窗口
点击按钮
关于c# - 我如何在 WPF 中模仿这种行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51561656/
这个问题在这里已经有了答案: How to test your code on a machine with big-endian architecture? (3 个答案) 关闭 4 年前。 我想
我正在使用 Mockito 对业务对象进行单元测试。业务对象使用通常从数据库获取数据的 DAO。为了测试业务对象,我意识到使用单独的内存 DAO(将数据保存在 HashMap 中)比编写所有 when
如何实现: if X in (1,2,3) then 而不是: if x=1 or x=2 or x=3 then 换句话说,如何才能最好地模仿 Excel 的 VBA 中的 IN 运算符? 最佳答案
我正在使用带有 Jabber-net 的 ejabberd 2。我想问你是否可以在使用管理员登录时冒充用户。意思是我希望能够使用管理员帐户登录并发送消息 From: 'User A', To: 'Us
当查询输入到 Excel 中的 Bloomberg BDH 函数中时,它会自动填充选定的单元格,并使用请求的数据填充下面的单元格。 我正在尝试创建一个执行类似操作的函数(尽管使用不同的数据源)。 BD
在 es6 中保留模拟静态属性的类的属性的最佳方法是什么? 使用原型(prototype)链中创建的属性安全吗? class Employee { constructor(name, creato
我有一个 HTML 文本输入 用户输入字符串。由于它是文本输入而不是文本区域,因此用户无法输入换行符。 用户可以在文本输入中输入 Markdown 元素,以便在稍后重新显示数据时格式化数据。然而,他们
我有一个快速的问题:我正在使用 Spyder,变量浏览器选项卡中有一个巧妙的功能,我可以单击标题并对列进行排序。但是,当我尝试使用时无法重现相同的排序顺序: df.sort_values() 在 py
这是一个有趣的挑战。我正在阅读 TypeScript github 中的这个老问题 support Extension Methods用法与C#类似。提出了两种主要方法,一种是添加语法糖来扩展经常令人
在 Java 中这是有效的: class Class1 { T t; ... } //Inside other class that has no relation to Class1 private
我有另一个对象,我希望它的颜色与 UITextField 的默认占位符文本颜色相同。 我知道我可以简单地创建一个具有相同颜色的新 UIColor,但如果 Apple 更改默认的 UITextField
我正在尝试为我的 ListView 项目构建一个类似于 Gmail 应用程序标签列表的布局,其中标签文本在左侧,计数在右侧。除了长文本,我的大部分工作都有效。我所得到的结果导致文本与计数重叠。 这就是
我用一副纸牌创建了一个圆圈,用户可以旋转它来选择一张纸牌。平移结束后,它会捕捉到指定的角度,并带有漂亮的减速动画。将来会有某种指示表明 45 度的卡是所选的卡。我想指出选择随着触觉反馈而改变,就像在
我有一个简单的链表类型和一个 Clone 的实现它: #[deriving(Show)] enum List { Cons(int, Box), Nil, } impl Clone f
所以我创建了自己的自定义 UIView,它看起来像一个警报,现在我想添加显示和隐藏动画。 我想为 AlertController 模仿 Apple 的默认动画。解雇是一个简单的淡入淡出动画,但是我不确
我正在尝试让我的 Javascript 生活变得更轻松一些(至少对于我的工作环境而言)。我试图将所有 Javascript 对象创建方法移至“类”中。我有以下代码(用于创建超链接): function
您将如何模仿 iPhone 的键盘输入。因此,当您单击一个时,会显示 1,然后显示 2,然后显示 12... 依此类推,并显示 ( ) -。我不想使用实际的电话应用程序,因为我正在创建一个虚假的拨号器
你好,我有一个问题,我需要一些指导/帮助来创建一个菜单,如果屏幕太小而无法显示原始菜单,该菜单将替换为一个按钮。我知道 Bootstrap 会为您做这件事,但由于实现限制,我无法使用该库。因此,我查看
我正在使用 UIBarButtonItems 来触发特殊操作,但我还想在屏幕底部添加另一个按钮,其尺寸与在 NavigationBar 中创建的按钮的尺寸相同,我该怎么做? 我可以在 Interfac
我可以原谅可能重复的问题,但我没有找到解决问题的方法。 Controller 加载时模拟按钮点击。它运行良好,直到我将 ng-click 更改为 on-tap( ionic 应用程序)。现在根本不起作
我是一名优秀的程序员,十分优秀!