WPF popup: как сделать многоразовый шаблон для всплывающих окон? - PullRequest
5 голосов
/ 09 сентября 2010

Поскольку Popup не является производным от Control и не имеет шаблона, как я могу определить шаблон, чтобы все всплывающие окна выглядели одинаково?Мне нужно спроектировать тот, который имеет определенный внешний вид и не хочет копировать разметку каждый раз, когда его используют.

Это кажется довольно простым, но я не могу понять, как это сделать.Свойство Child определяет логическое дерево, но я не понимаю, как вы можете извлечь это из шаблона и использовать его повторно.

Ответы [ 2 ]

0 голосов
/ 02 июля 2019

Я хотел сделать то же самое, и вот что я придумал:

Я унаследовал от ContentPresenter, стилизовал этот элемент управления так, как хотел, и затем поместил производное ContentPresenter в мой Popup, я использовал только 2 текстовых блока для простоты, но легко понять, как можно добавить любой контент.

Мой пользовательский элемент управления:

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

0 голосов
/ 09 сентября 2010

Зависит от поведения ваших всплывающих окон. Если они предназначены только для отображения информации единообразным образом, то вам может потребоваться класс, производный от Window, который имеет стандартные форматы и стили, заключенные в ContentPresenter, а затем связывает содержимое докладчика со свойством который может представлять пользовательскую информацию для каждого всплывающего окна.

Тогда нужно просто программно вставить любой пользовательский контент перед тем, как отобразить всплывающее окно.

Надеюсь, это поможет.

...