如何为弹出控件编写样式模板?

17

我在一个应用程序 (.NET Framework 4, WPF) 中有很多弹出窗口,我需要将一个样式应用到它们所有的弹出窗口上。例如,一个弹出窗口看起来像这样:

<Popup PopupAnimation="Fade" MinWidth="600" MinHeight="200" Placement="Center" VerticalAlignment="Center" HorizontalAlignment="Center" IsEnabled="True" IsOpen="False">
    <Grid Width="Auto" Height="Auto" Background="Gray">
        <Grid.RowDefinitions>
            <RowDefinition Height="30"/>                   
            <RowDefinition Height="Auto"/>           
        </Grid.RowDefinitions>
        <Border BorderThickness="2" CornerRadius="8" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.RowSpan="2">
            <Border.BorderBrush>
                <SolidColorBrush Color="Gray"/>
            </Border.BorderBrush>
            <Border.Background>
                <SolidColorBrush Color="White"/>
            </Border.Background>
        </Border>

        <StackPanel Grid.Row="0">
            <Label Foreground="Blue" Content="Popup_Title"/>
        </StackPanel>

        <GroupBox Grid.Row="1" Header="Popup example content">
            <StackPanel>                      
                   ...                           
            </StackPanel>
        </GroupBox>      
    </Grid>
</Popup>

如何将边框和背景等样式应用到样式模板中? 我无法编写带有TargetType Popup的 Style 并修改它的 Property="Template",因为 Popup 控件没有 Property="Template"。那么我该如何为这些 Popups 编写样式?

编辑: 精确的工作样式:

    <Style x:Key="PopupContentStyle" TargetType="ContentControl">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ContentControl">
                <Grid Width="Auto" Height="Auto" Background="Gray">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="30"/>
                        <RowDefinition Height="Auto"/>
                    </Grid.RowDefinitions>
                    <Border BorderThickness="2" CornerRadius="8" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.RowSpan="2">
                        <Border.BorderBrush>
                            <SolidColorBrush Color="Gray"/>
                        </Border.BorderBrush>
                        <Border.Background>
                            <SolidColorBrush Color="White"/>
                        </Border.Background>
                    </Border>

                    <StackPanel Grid.Row="0">
                        <Label Foreground="Blue" Content="Popup_Title"/>
                    </StackPanel>

                    <GroupBox Grid.Row="1" Header="Popup example content">
                        <StackPanel>
                            <ContentPresenter />
                        </StackPanel>
                    </GroupBox>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
2个回答

32
我建议将弹出窗口的内容包裹在类似于ContentControlHeaderedContentControl的东西中,并设置其样式。
<Popup>
    <ContentControl Style="{StaticResource PopupContentStyle}">
        ...
    </ContentControl>
</Popup>

示例样式...

<Style x:Key="PopupContentStyle" TargetType="{x:Type ContentControl}">
    <Setter Property="ContentTemplate">
        <Setter.Value>
            <DataTemplate>

                <Grid Width="Auto" Height="Auto" Background="Gray">
                   <Grid.RowDefinitions>
                        <RowDefinition Height="30"/>                   
                        <RowDefinition Height="Auto"/>           
                    </Grid.RowDefinitions>
                    <Border BorderThickness="2" CornerRadius="8" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.RowSpan="2">
                        <Border.BorderBrush>
                            <SolidColorBrush Color="Gray"/>
                        </Border.BorderBrush>
                        <Border.Background>
                            <SolidColorBrush Color="White"/>
                        </Border.Background>
                    </Border>

                    <StackPanel Grid.Row="0">
                        <Label Foreground="Blue" Content="Popup_Title"/>
                    </StackPanel>

                    <GroupBox Grid.Row="1" Header="Popup example content">
                        <StackPanel>                      
                               <ContentPresenter />                         
                        </StackPanel>
                   </GroupBox>      
                </Grid>
            </DataTemplate>
        </Setter.Value>
    </Setter>
</Style>

2
我不得不做一些更改才能使这个解决方案起作用,但这个想法正是我所需要的。非常感谢! - Marta
3
我必须这样定义ContentPresenter,否则这个解决方案就无法工作。但是这个想法本身正是我所需要的 - 也谢谢你!<ContentPresenter Content="{TemplateBinding ContentControl.Content}" /> - Mariusz Schimke

0

我更喜欢Rachels和Josh Noes的答案,但是遇到了一些麻烦,因为在我看来,应该在样式中定义ContentControl的属性Template,而不是ContentTemplate。将其设置为ControlTemplate的值(而不是DataTemplate),并不要忘记它的TargetType。否则,在我的情况下,解决方案无法正常工作。但这是一个真正惊人的想法,谢谢。


<Style x:Key="PopupContentStyle" TargetType="{x:Type ContentControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ContentControl">
                        ...
                        <!--Do some templatestuff around Presenter-->                      
                               <ContentPresenter />                         
                        <!--/Do some templatestuff around Presenter-->
                   </GroupBox>      
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接