【发布时间】:2018-08-14 05:36:48
【问题描述】:
所以我正在开发一个 C#/WPF 应用程序,而且我对语言/环境还比较陌生。几周前,我问了这个问题:How can I mimic this behavior in WPF?
我想创建一种伪模态弹出窗口,只需单击一个按钮即可出现/消失。根据给我的答案,我创建了以下两个类:
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
namespace RelayC
{
public partial class PopupBase : UserControl
{
public PopupBase()
{
this.Opacity = 0.0;
this.Visibility = Visibility.Hidden;
}
private void OpenPopup()
{
this.Opacity = 1.0;
this.Visibility = Visibility.Visible;
}
private void ClosePopup()
{
this.Opacity = 0.0;
this.Visibility = Visibility.Hidden;
}
public bool IsOpen
{
get { return (bool)GetValue(IsOpenProperty); }
set { SetValue(IsOpenProperty, value); }
}
public static readonly DependencyProperty IsOpenProperty =
DependencyProperty.Register(nameof(IsOpen),
typeof(bool),
typeof(PopupBase),
new PropertyMetadata(false,
new PropertyChangedCallback((s, e) =>
{
if (s is PopupBase popupBase && e.NewValue is bool boolean)
{
if (boolean)
{
popupBase.OpenPopup();
}
else
{
popupBase.ClosePopup();
}
}
})));
}
public class PopupAttach
{
public static PopupBase GetPopup(ButtonBase button)
=> (PopupBase)button.GetValue(PopupProperty);
public static void SetPopup(ButtonBase button, PopupBase value)
=> button.SetValue(PopupProperty, value);
public static readonly DependencyProperty PopupProperty =
DependencyProperty.RegisterAttached("Popup",
typeof(PopupBase),
typeof(PopupAttach),
new PropertyMetadata(null,
new PropertyChangedCallback((s, e) =>
{
if (s is ButtonBase button && e.NewValue is PopupBase newPopup)
{
if (Application.Current.MainWindow.Content is Grid grid)
{
if (e.OldValue is PopupBase oldPopup)
{
grid.Children.Remove(oldPopup);
}
grid.Children.Add(newPopup);
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)
{
newPopup.IsOpen = true;
}
}
})));
}
}
然后我创建的任何 UserControl 都从 PopupBase 继承,所以我的 Popup UI 看起来有点像这样:
<local:PopupBase x:Class="RelayC.AddServer"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:RelayC"
mc:Ignorable="d"
Width="500"
Height="375">
UI CONTENT INSERTED HERE
</local:PopupBase>
问题是当我想把它附加到一个按钮上时,我必须这样做:
<Window.Resources>
<local:AddServer Grid.Row="1" x:Key="ISERCpm"/>
</Window.Resources>
在我的 MainWindow.xaml 中,然后使用按钮从按钮调用它
<Button local:PopupAttach.Popup="{StaticResource ISERCpm}" />
有没有办法跳过窗口资源声明直接调用我的 PopupBase 用户控件?
【问题讨论】:
标签: c# wpf user-controls dependency-properties