【问题标题】:Focus and Selection Styling listbox items with multiple possible templates具有多个可能模板的焦点和选择样式列表框项目
【发布时间】:2010-10-27 21:54:07
【问题描述】:

下午好,

我有一个列表框,它使用来自模型、地址和 RAddresses(继承自地址)的项目列表

现在,以前我一直在 ItemContainerStyle 中创建我的项目模板,因此我只有自己的焦点视觉效果(即没有虚线,没有浅灰色矩形等)。这在过去运行良好。

我现在需要两个模板,每个类型(地址和 RAddress)一个。我在 ListBox.resources 中创建了这些作为默认模板(示例如下):

<DataTemplate DataType="{x:Type DAL:RAddress}">

我的列表框的 ItemContainerStyle 属性也指向以下内容:

    <Style x:Key="AddressContainerStyle" TargetType="{x:Type ListBoxItem}">
        <Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
        <Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
        <Setter Property="Padding" Value="0,0,0,0"/>
        <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
    </Style>

以前当模板应用于样式时,这会阻止显示虚线和灰色矩形视觉对象。但是,现在他们这样做了,我设置的 VisualState 设置似乎没有得到应用。

整个 DataTemplate 示例如下:

<DataTemplate DataType="{x:Type DAL:Address}">
<Border x:Name="Bd" SnapsToDevicePixels="true" Background="#4C000000" CornerRadius="10" Padding="0" BorderBrush="#00FF0000" BorderThickness="1">
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="SelectionStates">
            <VisualState x:Name="Unselected"/>
            <VisualState x:Name="Selected">
                <Storyboard>
                    <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="Bd">
                        <EasingColorKeyFrame KeyTime="0" Value="#80000000"/>
                    </ColorAnimationUsingKeyFrames>
                    <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="Bd">
                        <EasingColorKeyFrame KeyTime="0" Value="#00FF0000"/>
                    </ColorAnimationUsingKeyFrames>
                </Storyboard>
            </VisualState>
            <VisualState x:Name="SelectedUnfocused">
                <Storyboard>
                    <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="Bd">
                        <EasingColorKeyFrame KeyTime="0" Value="#80000000"/>
                    </ColorAnimationUsingKeyFrames>
                    <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="Bd">
                        <EasingColorKeyFrame KeyTime="0" Value="Red"/>
                    </ColorAnimationUsingKeyFrames>
                </Storyboard>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups> 
    <Grid Height="Auto" Width="Auto">
        <CheckBox x:Name="checkBox" Content="CheckBox" Margin="0" VerticalAlignment="Top" d:LayoutOverrides="Width" Style="{DynamicResource EditGemStyle}" HorizontalAlignment="Right" IsChecked="{Binding EditMode}"/>
        <StackPanel Margin="0" Orientation="Vertical" d:LayoutOverrides="Height">
            <Grid x:Name="DisplayGrid" Height="Auto" Width="Auto" d:LayoutOverrides="Width" VerticalAlignment="Stretch" Margin="7,3,11,3">
                <StackPanel Orientation="Vertical" Width="Auto" d:LayoutOverrides="Width, Height" Margin="0,0,10,0">
                    <TextBlock x:Name="AddressFriendlyName" TextWrapping="Wrap" Text="{Binding AddressFriendlyName}" FontSize="18.667" Style="{DynamicResource Data}"/>
                    <TextBlock x:Name="Address1" TextWrapping="Wrap" Text="{Binding Address1}" d:LayoutOverrides="Width" FontSize="13.333" Style="{DynamicResource Data}"/>
                    <TextBlock x:Name="Address2" TextWrapping="Wrap" Text="{Binding Address2}" FontSize="13.333" Style="{DynamicResource Data}"/>
                    <TextBlock x:Name="Address3" TextWrapping="Wrap" Text="{Binding Address3}" FontSize="13.333" Style="{DynamicResource Data}"/>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock x:Name="City" TextWrapping="Wrap" Text="{Binding City}" FontSize="13.333" Style="{DynamicResource Data}"/>
                        <TextBlock TextWrapping="Wrap" Text=", " FontSize="13.333" Style="{DynamicResource Data}"/>
                        <TextBlock x:Name="State" TextWrapping="Wrap" Text="{Binding State}" Margin="0,0,5,0" FontSize="13.333" Style="{DynamicResource Data}"/>
                        <TextBlock x:Name="ZIP" TextWrapping="Wrap" Text="{Binding ZIP}" FontSize="13.333" Style="{DynamicResource Data}"/>
                    </StackPanel>
                    <TextBlock x:Name="Country" TextWrapping="Wrap" Text="{Binding Country}" FontSize="13.333" Style="{DynamicResource Data}"/>
                </StackPanel>
            </Grid>
            <Grid x:Name="EditGrid" Height="Auto" Margin="7,3,11,0" Visibility="Collapsed">
                <StackPanel Orientation="Vertical" Width="Auto" Margin="0,0,10,0" d:LayoutOverrides="Width, Height">
                    <TextBox x:Name="AddressFriendlyName1" TextWrapping="Wrap" Text="{Binding AddressFriendlyName}" Template="{DynamicResource SnazzyTextBoxTemplate}" Margin="0,2" Foreground="White"/>
                    <TextBox x:Name="Address4" TextWrapping="Wrap" Text="{Binding Address1}" d:LayoutOverrides="Width" Template="{DynamicResource SnazzyTextBoxTemplate}" Margin="0,2" Foreground="White"/>
                    <TextBox x:Name="Address5" TextWrapping="Wrap" Text="{Binding Address2}" Template="{DynamicResource SnazzyTextBoxTemplate}" Margin="0,2" Foreground="White"/>
                    <TextBox x:Name="Address6" TextWrapping="Wrap" Text="{Binding Address3}" Template="{DynamicResource SnazzyTextBoxTemplate}" Margin="0,2" Foreground="White"/>
                    <StackPanel Orientation="Horizontal">
                        <TextBox x:Name="City1" TextWrapping="Wrap" Text="{Binding City}" Template="{DynamicResource SnazzyTextBoxTemplate}" Margin="0,2" Foreground="White"/>
                        <TextBlock TextWrapping="Wrap" Text=", " Foreground="White"/>
                        <TextBox x:Name="State1" TextWrapping="Wrap" Text="{Binding State}" Margin="0,2,5,2" Template="{DynamicResource SnazzyTextBoxTemplate}" Foreground="White"/>
                        <TextBox x:Name="ZIP1" TextWrapping="Wrap" Text="{Binding ZIP}" Template="{DynamicResource SnazzyTextBoxTemplate}" Margin="0,2" Foreground="White"/>
                    </StackPanel>
                    <TextBox x:Name="Country1" TextWrapping="Wrap" Text="{Binding Country}" Template="{DynamicResource SnazzyTextBoxTemplate}" Margin="0,2" Foreground="White"/>
                </StackPanel>
            </Grid>
        </StackPanel>
    </Grid>
</Border>
<DataTemplate.Triggers>
    <DataTrigger Binding="{Binding Address2}" Value="{x:Null}">
        <Setter TargetName="Address2" Property="Visibility" Value="Collapsed"/>
    </DataTrigger>
    <DataTrigger Binding="{Binding Address3}" Value="{x:Null}">
        <Setter TargetName="Address3" Property="Visibility" Value="Collapsed"/>
    </DataTrigger>
    <DataTrigger Binding="{Binding EditMode}" Value="False">
        <Setter Property="Visibility" TargetName="DisplayGrid" Value="Visible"/>
        <Setter Property="Visibility" TargetName="EditGrid" Value="Collapsed"/> 
    </DataTrigger>
    <DataTrigger Binding="{Binding EditMode}" Value="True">
        <Setter Property="Visibility" TargetName="DisplayGrid" Value="Collapsed"/>
        <Setter Property="Visibility" TargetName="EditGrid" Value="Visible"/> 
    </DataTrigger>
</DataTemplate.Triggers>

以前我曾尝试使用 StyleSelector 在创建的 ItemContainerStyles 之间进行选择(每种类型一个)。这导致我遇到错误“无法在不可变对象实例上为 '(0).(1)' 设置动画”,因此我开始查看我目前的设置。

如何在同一个 ListBox 中托管的两个单独的项目模板上强制执行我自己的焦点和选择样式?

任何帮助将不胜感激。

【问题讨论】:

    标签: wpf datatemplate styling itemcontainerstyle


    【解决方案1】:

    我认为您需要将情节提要的规范移至 ItemContainerStyle,而不是在 DataTemplates 本身中指定它们。这更干燥,并发症更少。

    <Window.Resources>
    
        <DataTemplate DataType="{x:Type DAL:RAddress}">
            <TextBlock>RAddress!</TextBlock>
        </DataTemplate>
    
        <DataTemplate DataType="{x:Type DAL:Address}">
            <TextBlock>Address!</TextBlock>
        </DataTemplate>
        <Style x:Key="IHateDottedBorders" TargetType="{x:Type ListBoxItem}">
            <Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
            <Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
            <Setter Property="Padding" Value="0,0,0,0"/>
            <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ListBoxItem}">
                        <Border x:Name="Bd" SnapsToDevicePixels="true" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}">
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="SelectionStates">
                                    <VisualState x:Name="Unselected"/>
                                    <VisualState x:Name="Selected">
                                        <Storyboard>
                                            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="Bd">
                                                <EasingColorKeyFrame KeyTime="0" Value="#80000000"/>
                                            </ColorAnimationUsingKeyFrames>
                                            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="Bd">
                                                <EasingColorKeyFrame KeyTime="0" Value="#00FF0000"/>
                                            </ColorAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="SelectedUnfocused">
                                        <Storyboard>
                                            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="Bd">
                                                <EasingColorKeyFrame KeyTime="0" Value="#80000000"/>
                                            </ColorAnimationUsingKeyFrames>
                                            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="Bd">
                                                <EasingColorKeyFrame KeyTime="0" Value="Red"/>
                                            </ColorAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsSelected" Value="true">
                                <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                                <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
                            </Trigger>
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="IsSelected" Value="true"/>
                                    <Condition Property="Selector.IsSelectionActive" Value="false"/>
                                </MultiTrigger.Conditions>
                                <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
                                <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
                            </MultiTrigger>
                            <Trigger Property="IsEnabled" Value="false">
                                <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    
    
    </Window.Resources>
    
    <Grid>
        <ListBox ItemContainerStyle="{StaticResource IHateDottedBorders}" ItemsSource="{Binding CollectionOfAddresses}" />
    </Grid>
    

    【讨论】:

    • 当单击列表框项时,上述样式返回讨厌的“无法在不可变对象实例上设置动画'(0).(1)'”错误。我还尝试了一个您之前给我的示例,其样式由 Visualstates 的 setter 组成,但 VisualState 和 VisualStateManager 没有有效的 setter。还有其他想法吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-08
    • 1970-01-01
    • 2014-01-23
    • 1970-01-01
    • 1970-01-01
    • 2011-11-08
    相关资源
    最近更新 更多