简体   繁体   中英

When ItemsControl.ItemContainerStyle is specified together with ItemsControl.ItemTemplateSelector, the later is ignored

I have the following code - only 3 classes:

MainWindow.xaml

 <Window x:Class="WpfApp4.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp4"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
<Window.Resources>

    <Style x:Key="ComboBoxItemStyle" TargetType="{x:Type ComboBoxItem}">
        <Setter Property="UIElement.SnapsToDevicePixels"
        Value="True" />
        <Setter Property="Control.Padding"
        Value="4,1" />
        <Setter Property="Control.HorizontalContentAlignment">
            <Setter.Value>
                <Binding Path="HorizontalContentAlignment"
                 RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=ItemsControl, AncestorLevel=1}" />
            </Setter.Value>
        </Setter>
        <Setter Property="Control.VerticalContentAlignment">
            <Setter.Value>
                <Binding Path="VerticalContentAlignment"
                 RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=ItemsControl, AncestorLevel=1}" />
            </Setter.Value>
        </Setter>
        <Setter Property="Panel.Background"
        Value="#00FFFFFF" />
        <Setter Property="Border.BorderBrush"
        Value="#00FFFFFF" />
        <Setter Property="Border.BorderThickness"
        Value="1" />
        <Setter Property="FrameworkElement.FocusVisualStyle">
            <Setter.Value>
                <Style TargetType="{x:Type IFrameworkInputElement}">
                    <Setter Property="Control.Template">
                        <Setter.Value>
                            <ControlTemplate>
                                <Rectangle Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"
                                   StrokeThickness="1"
                                   StrokeDashArray="1 2"
                                   Margin="2"
                                   SnapsToDevicePixels="True" />
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </Setter.Value>
        </Setter>
        <Setter Property="Control.Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ComboBoxItem}">
                    <Border BorderThickness="{TemplateBinding Border.BorderThickness}"
                    Padding="{TemplateBinding Control.Padding}"
                    BorderBrush="{TemplateBinding Border.BorderBrush}"
                    Background="{TemplateBinding Panel.Background}"
                    Name="Bd"
                    SnapsToDevicePixels="True">
                        <ContentPresenter Content="{TemplateBinding ContentControl.Content}"
                                  ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
                                  ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}"
                                  HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
                                  VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}"
                                  SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="UIElement.IsEnabled"
                         Value="False">
                            <Setter Property="TextElement.Foreground"
                            TargetName="Bd"
                            Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
                        </Trigger>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="Selector.IsSelected"
                                   Value="False" />
                                <Condition Property="UIElement.IsMouseOver"
                                   Value="True" />
                                <Condition Property="UIElement.IsKeyboardFocused"
                                   Value="False" />
                            </MultiTrigger.Conditions>
                            <Setter Property="Panel.Background"
                            TargetName="Bd"
                            Value="#1F26A0DA" />
                            <Setter Property="Border.BorderBrush"
                            TargetName="Bd"
                            Value="#A826A0DA" />
                        </MultiTrigger>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="Selector.IsSelected"
                                   Value="True" />
                                <Condition Property="UIElement.IsMouseOver"
                                   Value="False" />
                                <Condition Property="UIElement.IsKeyboardFocused"
                                   Value="True" />
                            </MultiTrigger.Conditions>
                            <Setter Property="Panel.Background"
                            TargetName="Bd"
                            Value="#3D26A0DA" />
                            <Setter Property="Border.BorderBrush"
                            TargetName="Bd"
                            Value="#26A0DA" />
                        </MultiTrigger>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="Selector.IsSelected"
                                   Value="True" />
                                <Condition Property="UIElement.IsMouseOver"
                                   Value="True" />
                            </MultiTrigger.Conditions>
                            <Setter Property="Panel.Background"
                            TargetName="Bd"
                            Value="#2E0080FF" />
                            <Setter Property="Border.BorderBrush"
                            TargetName="Bd"
                            Value="#99006CD9" />
                        </MultiTrigger>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="Selector.IsSelected"
                                   Value="True" />
                                <Condition Property="UIElement.IsMouseOver"
                                   Value="False" />
                                <Condition Property="UIElement.IsKeyboardFocused"
                                   Value="False" />
                            </MultiTrigger.Conditions>
                            <Setter Property="Panel.Background"
                            TargetName="Bd"
                            Value="#3DDADADA" />
                            <Setter Property="Border.BorderBrush"
                            TargetName="Bd"
                            Value="#DADADA" />
                        </MultiTrigger>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="Selector.IsSelected"
                                   Value="False" />
                                <Condition Property="UIElement.IsMouseOver"
                                   Value="False" />
                                <Condition Property="UIElement.IsKeyboardFocused"
                                   Value="True" />
                            </MultiTrigger.Conditions>
                            <Setter Property="Border.BorderBrush"
                            TargetName="Bd"
                            Value="#26A0DA" />
                        </MultiTrigger>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="Selector.IsSelected"
                                   Value="False" />
                                <Condition Property="UIElement.IsMouseOver"
                                   Value="True" />
                                <Condition Property="UIElement.IsKeyboardFocused"
                                   Value="True" />
                            </MultiTrigger.Conditions>
                            <Setter Property="Panel.Background"
                            TargetName="Bd"
                            Value="#5426A0DA" />
                            <Setter Property="Border.BorderBrush"
                            TargetName="Bd"
                            Value="#26A0DA" />
                        </MultiTrigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>





    <DataTemplate x:Key="SelectedItemTemplate">
    <TextBlock Text="{Binding}" Background="Yellow"></TextBlock>
</DataTemplate>

<DataTemplate x:Key="DropdownItemTemplate">
    <TextBlock Text="{Binding}" Background="Red"></TextBlock>
    </DataTemplate>

    <local:TemplateSelector x:Key="TemplateSelector" SelectedTemplate="{StaticResource SelectedItemTemplate}"
                        ListItemTemplate="{StaticResource DropdownItemTemplate}" />
</Window.Resources>
<Grid>

    <ComboBox Height="80" Width="120" ItemTemplateSelector="{StaticResource TemplateSelector}" x:Name="TestComboBox" SelectedIndex="0" ItemsSource="{Binding Items}" ItemContainerStyle="{StaticResource ComboBoxItemStyle}"/>
</Grid>

MainWindow.xaml.cs

    using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApp4
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = this;
            this.Items = new ObservableCollection<string>() {"D1", "D2", "D3"};
        }

        public ObservableCollection<string> Items { get; set; }
    }
}

TemplateSelector

    using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace WpfApp4
{


    public class TemplateSelector : DataTemplateSelector
    {
      
        public DataTemplate SelectedTemplate { get; set; }

        
        public DataTemplate ListItemTemplate { get; set; }

        public override DataTemplate SelectTemplate(object serviceModel, DependencyObject container)
        {
            var itemControl = container;

            while (itemControl != null && !(itemControl is ComboBoxItem || itemControl is ComboBox))
                itemControl = VisualTreeHelper.GetParent(itemControl);

            return itemControl is ComboBoxItem ? ListItemTemplate : SelectedTemplate;
        }
    }
}

With the current code, DropdownItemTemplate is ignored, we don't get to the

override DataTemplate SelectTemplate 

method in the TemplateSelector for the comboboxItems.

If I remove the ItemContainerStyle="{StaticResource ComboBoxItemStyle}" from the ComboBox, then everything works perfectly.

I wonder why? Thank you!

I wonder why?

Because the ContentControl in your ControlTemplate sets the Content* properties explicitly. Try this:

<Border BorderThickness="{TemplateBinding Border.BorderThickness}"
        Padding="{TemplateBinding Control.Padding}"
        BorderBrush="{TemplateBinding Border.BorderBrush}"
        Background="{TemplateBinding Panel.Background}"
        Name="Bd"
        SnapsToDevicePixels="True">
    <ContentPresenter HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
                      VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}"
                      SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</Border>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM