代码之家  ›  专栏  ›  技术社区  ›  dex3703

WPF popup:如何为弹出窗口创建可重用的模板?

  •  4
  • dex3703  · 技术社区  · 16 年前

    由于弹出窗口不是从控件派生的,也没有模板,我如何定义模板以使所有弹出窗口看起来相同?我需要设计一个有一定的外观,不想每次使用都要复制标记。

    这看起来很容易,但我不知道怎么做。子属性定义了一个逻辑树,但我不知道如何将其提取到模板中并重用它。

    1 回复  |  直到 15 年前
        1
  •  0
  •   Val    16 年前

    取决于你希望你的弹出窗口如何表现。如果它们只是为了以统一的方式显示信息,那么您可能希望有一个派生自 Window 有标准格式和样式包装在 ContentPresenter 然后将演示者的内容绑定到一个属性,该属性可以表示每个弹出窗口的自定义信息。

    在显示弹出窗口之前,只需通过编程插入您想要的自定义内容。

    希望有帮助。

        2
  •  0
  •   marc_s MisterSmith    7 年前

    我想做同样的事,下面是我的想法:

    我继承自 ContentPresenter ,设置控件的样式,然后 任命者 在我的 Popup ,为了简单起见,我只使用了两个文本块,但是很容易理解如何添加任何内容。

    我的自定义控件:

    using System.Windows;
    using System.Windows.Controls;
    
    namespace CustomControls
    {
        [TemplatePart(Name = PART_PopupHeader, Type = typeof(TextBlock))]
        [TemplatePart(Name = PART_PopupContent, Type = typeof(TextBlock))]
    
        public class CustomPopupControl : ContentControl
        {
            private const string PART_PopupHeader = "PART_PopupHeader";
            private const string PART_PopupContent = "PART_PopupContent";
    
            private TextBlock _headerBlock = null;
            private TextBlock _contentBlock = null;
    
            static CustomPopupControl()
            {
                DefaultStyleKeyProperty.OverrideMetadata
                    (typeof(CustomPopupControl), 
                    new FrameworkPropertyMetadata(typeof(CustomPopupControl)));
            }
    
            public override void OnApplyTemplate()
            {
                base.OnApplyTemplate();
                _headerBlock = GetTemplateChild(PART_PopupHeader) as TextBlock;
                _contentBlock = GetTemplateChild(PART_PopupContent) as TextBlock;
            }
    
            public static readonly DependencyProperty HeaderTextProperty =
                DependencyProperty.Register("HeaderText", typeof(string), typeof(CustomPopupControl), new UIPropertyMetadata(string.Empty));
    
            public string HeaderText
            {
                get
                {
                    return (string)GetValue(HeaderTextProperty);
                }
                set
                {
                    SetValue(HeaderTextProperty, value);
                }
            }
    
            public static readonly DependencyProperty ContentTextProperty =
                DependencyProperty.Register("ContentText", typeof(string), typeof(CustomPopupControl), new UIPropertyMetadata(string.Empty));
    
            public string ContentText
            {
                get
                {
                    return (string)GetValue(ContentTextProperty);
                }
                set
                {
                    SetValue(ContentTextProperty, value);
                }
            }
        }
    }
    

    控件的样式:

    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                  
                    xmlns:local="clr-namespace:CustomControls">
    
    <Style TargetType="{x:Type local:CustomPopupControl}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:CustomPopupControl}">
                    <Border CornerRadius="3" BorderThickness="1" BorderBrush="White">
                        <Border.Background>
                            <SolidColorBrush Color="#4b4b4b" Opacity="0.75"/>
                        </Border.Background>
                        <Border.Effect>
                            <DropShadowEffect ShadowDepth="0"
                                Color="White"
                                Opacity="1"
                                BlurRadius="5"/>
                        </Border.Effect>
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="*"/>
                            </Grid.RowDefinitions>
                            <TextBlock Text="{TemplateBinding HeaderText}"
                                       Grid.Row="0"
                                       Foreground="#5095d6"
                                       FontWeight="Bold"
                                       VerticalAlignment="Bottom"
                                       Margin="{TemplateBinding Margin}"
                                       HorizontalAlignment="Left"/>
                            <Rectangle Grid.Row="1" Stroke="AntiqueWhite" Margin="1 0"></Rectangle>
                            <TextBlock Grid.Row="2"
                                       Grid.ColumnSpan="2"                                
                                       x:Name="PART_TooltipContents"
                                       Margin="5, 2"
                                       Text="{TemplateBinding ContentText}"
                                       TextWrapping="Wrap"
                                       MaxWidth="200"/>
                        </Grid>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    

    控件的使用:

    <StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Center">
        <Button x:Name="Button1" Content="Button with popup" HorizontalAlignment="Center">
        </Button>
        <Button x:Name="Button2" Content="Another button with popup" HorizontalAlignment="Center">
        </Button>
        <Popup  IsOpen="True"
            FlowDirection="LeftToRight"
            Margin="10"
            PlacementTarget="{Binding ElementName=Button1}" 
            Placement="top" 
            StaysOpen="True">
            <local2:CustomPopupControl HeaderText="Some Header Text" ContentText="Content Text that could be any text needed from a binding or other source" Margin="2">
    
            </local2:CustomPopupControl>
        </Popup>
        <Popup  IsOpen="True"
            FlowDirection="LeftToRight"
            Margin="10"
            PlacementTarget="{Binding ElementName=Button2}" 
            Placement="Bottom" 
            StaysOpen="True">
            <local2:CustomPopupControl HeaderText="Different header text" ContentText="Some other text" Margin="2">
    
            </local2:CustomPopupControl>
        </Popup>
    </StackPanel>
    

    我试图说明一些属性如何在所有控件中保持不变,其他属性如何在每个控件中自定义,其他属性如何绑定到 TemplatePart ,以下是最终结果:

    enter image description here