引用没有自定义键的UserControl吗?

时间:2018-08-14 05:36:48

标签: c# wpf user-controls dependency-properties

所以我正在研究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用户控件吗?

1 个答案:

答案 0 :(得分:1)

PopupAttach.Popup是附加的依赖项属性。可以使用属性元素语法代替属性语法:

<Button>
  <local:PopupAttach.Popup>
    <local:AddServer Grid.Row="1"/>
  </local:PopupAttach.Popup>
</Button>