XAML列表框设置为带标题的单选按钮组

时间:2018-04-26 15:38:40

标签: wpf xaml

我有这种风格:

<Style x:Key="RadioButtonList" TargetType="{x:Type ListBox}">
    <!-- ControlTemplate taken from MSDN http://msdn.microsoft.com/en-us/library/ms754242.aspx -->
    <Setter Property="SnapsToDevicePixels" Value="true"/>
    <Setter Property="OverridesDefaultStyle" Value="true"/>
    <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
    <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
    <Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
    <Setter Property="MinWidth" Value="120"/>
    <Setter Property="MinHeight" Value="80"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ListBox">
                <Border 
                    Name="Border" 
                    Background="Transparent"
                    BorderBrush="Transparent"
                    BorderThickness="0"
                    CornerRadius="2">
                    <ScrollViewer 
                        Margin="0"
                        Focusable="false">
                        <StackPanel Margin="2" IsItemsHost="True" />
                    </ScrollViewer>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter TargetName="Border" Property="Background" Value="Transparent" />
                        <Setter TargetName="Border" Property="BorderBrush" Value="Transparent" />
                    </Trigger>
                    <Trigger Property="IsGrouping" Value="true">
                        <Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="ItemContainerStyle">
        <Setter.Value>
            <Style TargetType="{x:Type ListBoxItem}" >
                <Setter Property="Margin" Value="2" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type ListBoxItem}">
                            <Border Name="theBorder" Background="Transparent">
                                <RadioButton Focusable="False"
                                    IsHitTestVisible="False"
                                    IsChecked="{TemplateBinding IsSelected}">
                                    <ContentPresenter />
                                </RadioButton>
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Setter.Value>
    </Setter>
</Style>

用作:

        <ListBox                     
            Grid.Column="2"
            Style="{StaticResource RadioButtonList}" 
            ItemsSource="{Binding ModosConsultaSaldos}" 
            DisplayMemberPath="Description"
            SelectedItem="{Binding ModoConsultaSaldos,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>

显示如下内容:

enter image description here

但现在我想使用相同的样式添加标题,

enter image description here

这是真的吗?怎么样?

1 个答案:

答案 0 :(得分:1)

这可以通过多种方式完成。最简单的方法就是在您使用XAML时将标签粘贴在ListBox的前面。但是如果你想强制执行一致的风格,你会想要比这更好的东西。

我们可以通过编写一个ListBox的子类来添加Header属性(我将称之为Header而不是Title,因为那样&#39 ; s内置的WPF控件会调用它)。

但稍微灵活一点的选择是将Header属性写为附加属性。我们还会引入HeaderTemplate附加属性,因此您可以适当地设置标题内容的样式。这是具有标题的控件中的常见WPF实践,例如MenuItemGroupBox。这些WPF控件也具有HeaderTemplateSelectorHeaderStringFormat属性;我会留下那些作为学生的练习。

首先,附加属性:除名称和类型外,这是所有样板文件。

public static class ListBoxEx
{
    public static Object GetHeader(ListBox obj)
    {
        return (Object)obj.GetValue(HeaderProperty);
    }

    public static void SetHeader(ListBox obj, Object value)
    {
        obj.SetValue(HeaderProperty, value);
    }

    public static readonly DependencyProperty HeaderProperty =
        DependencyProperty.RegisterAttached("Header", typeof(Object), typeof(ListBoxEx),
            new FrameworkPropertyMetadata(null) { AffectsMeasure = true, AffectsParentMeasure = true });


    public static Object GetHeaderTemplate(ListBox obj)
    {
        return (Object)obj.GetValue(HeaderTemplateProperty);
    }

    public static void SetHeaderTemplate(ListBox obj, Object value)
    {
        obj.SetValue(HeaderTemplateProperty, value);
    }

    public static readonly DependencyProperty HeaderTemplateProperty =
        DependencyProperty.RegisterAttached("HeaderTemplate", typeof(Object), typeof(ListBoxEx),
            new FrameworkPropertyMetadata(null) { AffectsMeasure = true, AffectsParentMeasure = true });
}

现在我们将这些添加到模板中:

...
<Setter.Value>
    <ControlTemplate TargetType="ListBox">
        <Border 
            Name="Border" 
            Background="Transparent"
            BorderBrush="Transparent"
            BorderThickness="0"
            CornerRadius="2"
            >
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="*" />
                </Grid.RowDefinitions>
                <ContentControl
                    Content="{TemplateBinding local:ListBoxEx.Header}"
                    ContentTemplate="{TemplateBinding local:ListBoxEx.HeaderTemplate}"
                    />
                <ScrollViewer 
                    Margin="0"
                    Focusable="false"
                    Grid.Row="1"
                    >
                    <StackPanel Margin="2" IsItemsHost="True" />
                </ScrollViewer>
            </Grid>
        </Border>

我们会为您的Style提供另一个setter,以创建一个默认的标题模板,用于执行屏幕截图中的下划线:

        <Setter Property="local:ListBoxEx.HeaderTemplate">
            <Setter.Value>
                <DataTemplate>
                    <Label 
                        Content="{Binding}"
                        BorderBrush="Black"
                        BorderThickness="0,0,0,1"
                        HorizontalAlignment="Left"
                        />
                </DataTemplate>
            </Setter.Value>
        </Setter>

我们这样使用它:

    <ListBox
        Style="{StaticResource RadioButtonList}"
        ItemsSource="{Binding ModosConsultaSaldos}"
        local:ListBoxEx.Header="Saldos"
        ...
        />
相关问题