内科 發表於 2025-7-10 16:55:00

WPF开发中重写Combox样式遇到的一些问题

<h1 id="在实际的wpf开发过程中你可能需要自定义combox的样式重写的样式可能不出效果背景色无法正常显示或者是显示的内容出现白色遮罩如以下的效果">在实际的WPF开发过程中,你可能需要自定义ComBox的样式,重写的样式可能不出效果,背景色无法正常显示,或者是显示的内容出现白色遮罩,如以下的效果:</h1>
<h2 id="1combox样式如下">1.ComBox样式如下:</h2>
<pre><code> &lt;Style TargetType="TextBlock" x:Key="BaseTextBlockStyle"&gt;
       &lt;Setter Property="FontSize" Value="14"/&gt;
       &lt;Setter Property="FontFamily" Value="Arial"/&gt;
       &lt;Setter Property="FontWeight" Value="Normal"/&gt;
       &lt;Setter Property="Opacity" Value="1"/&gt;
       &lt;Setter Property="Background" Value="{x:Null}"/&gt;
       &lt;Setter Property="Foreground" Value="White"/&gt;
       &lt;Setter Property="VerticalAlignment" Value="Center"/&gt;
       &lt;Setter Property="HorizontalAlignment" Value="Center"/&gt;
       &lt;Setter Property="Padding" Value="0"/&gt;
       &lt;!--&lt;Style.Triggers&gt;
               &lt;Trigger Property="IsMouseOver" Value="True"&gt;
                       &lt;Setter Property="Foreground" Value="White"/&gt;
                       &lt;Setter Property="Cursor" Value="Hand"/&gt;
               &lt;/Trigger&gt;
       &lt;/Style.Triggers&gt;--&gt;
&lt;/Style&gt;

&lt;Style x:Key="BaseComboBoxStyle" TargetType="ComboBox"&gt;
        &lt;Setter Property="FontSize" Value="14"/&gt;
        &lt;Setter Property="FontFamily" Value="Arial"/&gt;
        &lt;Setter Property="Margin" Value="5,0,5,0"/&gt;
        &lt;Setter Property="VerticalAlignment" Value="Center"/&gt;
        &lt;Setter Property="HorizontalAlignment" Value="Right"/&gt;
        &lt;Setter Property="Width" Value="160"/&gt;
        &lt;Setter Property="Height" Value="32"/&gt;
        &lt;Setter Property="Background" Value="#0D0D19"/&gt;
        &lt;Setter Property="BorderThickness" Value="0"/&gt;
        &lt;Setter Property="IsEditable" Value="False"/&gt;
        &lt;Setter Property="ItemTemplate"&gt;
                &lt;Setter.Value&gt;
                        &lt;DataTemplate&gt;
                                &lt;StackPanel Orientation="Horizontal"&gt;
                                        &lt;TextBlock Text="{Binding Name}" VerticalAlignment="Center" Margin="5,0,0,0" Style="{StaticResource ResourceKey=BaseTextBlockStyle}"/&gt;
                                &lt;/StackPanel&gt;
                        &lt;/DataTemplate&gt;
                &lt;/Setter.Value&gt;
        &lt;/Setter&gt;
&lt;/Style&gt;
</code></pre>
<p>页面展示如下:</p>
<pre><code> &lt;ComboBox   Tag="SelectTestPositonList"
                           ItemsSource="{Binding SelectTestPositonList, Mode=OneWay}"
                           SelectedItem="{Binding SelectTestPositionItem}"
                           SelectionChanged="ComboBox_SelectionChanged"&gt;
       &lt;ComboBox.ItemTemplate&gt;
               &lt;DataTemplate&gt;
                       &lt;StackPanel Orientation="Horizontal"&gt;
                               &lt;TextBlock Text="{Binding Name}" VerticalAlignment="Center" Margin="5,0,0,0" Style="{StaticResource ResourceKey=BaseTextBlockStyle}"/&gt;
                       &lt;/StackPanel&gt;
               &lt;/DataTemplate&gt;
       &lt;/ComboBox.ItemTemplate&gt;
&lt;/ComboBox&gt;
</code></pre>
<p>运行效果如下:</p>
<p><img src="https://img2024.cnblogs.com/blog/2212230/202507/2212230-20250710164726654-1126209127.png"></p>
<p><img src="https://img2024.cnblogs.com/blog/2212230/202507/2212230-20250710165338102-1756235764.png"></p>
<h2 id="2原因">2.原因</h2>
<p>这是因为 <strong>WPF 默认的 ComboBox 模板中</strong>,其子元素(如 ToggleButton、ContentPresenter、Popup 等)有独立的样式,你仅仅设置 Background 并不会影响内部结构,尤其是:</p>
<ul>
<li>下拉按钮(ToggleButton)</li>
<li>选中项显示区域</li>
<li>下拉列表(Popup)</li>
</ul>
<p>解决方案:<strong>重写 ComboBox 的控件模板</strong>(ControlTemplate)</p>
<h2 id="3重写样式">3.重写样式:</h2>
<pre><code>&lt;Style TargetType="TextBlock" x:Key="BaseTextBlockStyle"&gt;
        &lt;Setter Property="FontSize" Value="14"/&gt;
        &lt;Setter Property="FontFamily" Value="Arial"/&gt;
        &lt;Setter Property="FontWeight" Value="Normal"/&gt;
        &lt;Setter Property="Opacity" Value="1"/&gt;
        &lt;Setter Property="Background" Value="{x:Null}"/&gt;
        &lt;Setter Property="Foreground" Value="White"/&gt;
        &lt;Setter Property="VerticalAlignment" Value="Center"/&gt;
        &lt;Setter Property="HorizontalAlignment" Value="Center"/&gt;
        &lt;Setter Property="Padding" Value="0"/&gt;
        &lt;!--&lt;Style.Triggers&gt;
                &lt;Trigger Property="IsMouseOver" Value="True"&gt;
                        &lt;Setter Property="Foreground" Value="White"/&gt;
                        &lt;Setter Property="Cursor" Value="Hand"/&gt;
                &lt;/Trigger&gt;
        &lt;/Style.Triggers&gt;--&gt;
&lt;/Style&gt;

&lt;Style x:Key="BaseComboBoxStyle" TargetType="ComboBox"&gt;
        &lt;Setter Property="Foreground" Value="White"/&gt;
        &lt;Setter Property="Background" Value="#0D0D19"/&gt;
        &lt;Setter Property="BorderThickness" Value="0"/&gt;
        &lt;Setter Property="FontSize" Value="14"/&gt;
        &lt;Setter Property="FontFamily" Value="Arial"/&gt;
        &lt;Setter Property="Width" Value="160"/&gt;
        &lt;Setter Property="Height" Value="32"/&gt;
        &lt;Setter Property="HorizontalAlignment" Value="Right"/&gt;
        &lt;Setter Property="VerticalAlignment" Value="Center"/&gt;
        &lt;Setter Property="Margin" Value="5,0,5,0"/&gt;
        &lt;Setter Property="IsEditable" Value="False"/&gt;
        &lt;Setter Property="ItemTemplate"&gt;
                &lt;Setter.Value&gt;
                        &lt;DataTemplate&gt;
                                &lt;StackPanel Orientation="Horizontal"&gt;
                                        &lt;TextBlock Text="{Binding Name}" Margin="5,0,0,0" Style="{StaticResource BaseTextBlockStyle}" /&gt;
                                &lt;/StackPanel&gt;
                        &lt;/DataTemplate&gt;
                &lt;/Setter.Value&gt;
        &lt;/Setter&gt;
        &lt;Setter Property="Template"&gt;
                &lt;Setter.Value&gt;
                        &lt;ControlTemplate TargetType="ComboBox"&gt;
                                &lt;Grid&gt;
                                        &lt;ToggleButton
                                                Name="ToggleButton"
                                                IsChecked="{Binding Path=IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
                                                ClickMode="Press"
                                                Background="{TemplateBinding Background}"
                                                BorderThickness="{TemplateBinding BorderThickness}" Width="{TemplateBinding Width}"&gt;
                                                &lt;Grid&gt;
                                                        &lt;ContentPresenter
                                                                Name="ContentSite"
                                                                IsHitTestVisible="False"
                                                                Content="{TemplateBinding SelectionBoxItem}"
                                                                ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
                                                                VerticalAlignment="Center"
                                                                HorizontalAlignment="Left" Width="160"
                                                                Margin="6,0,0,0"
                                                                RecognizesAccessKey="True"/&gt;
                                                        &lt;Path
                                                                HorizontalAlignment="Right"
                                                                Margin="0,0,6,0"
                                                                VerticalAlignment="Center"
                                                                Data="M 0 0 L 4 4 L 8 0 Z"
                                                                Fill="White"/&gt;
                                                &lt;/Grid&gt;
                                        &lt;/ToggleButton&gt;
                                        &lt;Popup
                                                Name="Popup"
                                                Placement="Bottom"
                                                IsOpen="{TemplateBinding IsDropDownOpen}"
                                                AllowsTransparency="True"
                                                Focusable="False"
                                                PopupAnimation="Slide"&gt;
                                                &lt;Grid
                                                        Name="DropDown"
                                                        SnapsToDevicePixels="True"
                                                        MinWidth="{TemplateBinding ActualWidth}"
                                                        MaxHeight="200"
                                                        Background="#0D0D19"&gt;
                                                        &lt;Border x:Name="DropDownBorder" BorderThickness="0" Background="#0D0D19"/&gt;
                                                        &lt;ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True"&gt;
                                                                &lt;StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" /&gt;
                                                        &lt;/ScrollViewer&gt;
                                                &lt;/Grid&gt;
                                        &lt;/Popup&gt;
                                &lt;/Grid&gt;
                                &lt;ControlTemplate.Triggers&gt;
                                        &lt;Trigger Property="HasItems" Value="false"&gt;
                                                &lt;Setter TargetName="DropDownBorder" Property="MinHeight" Value="95"/&gt;
                                        &lt;/Trigger&gt;
                                        &lt;Trigger Property="IsEnabled" Value="false"&gt;
                                                &lt;Setter Property="Foreground" Value="Gray"/&gt;
                                        &lt;/Trigger&gt;
                                        &lt;Trigger Property="IsMouseOver" Value="True"&gt;
                                                &lt;Setter Property="Background" Value="#1A1A2A"/&gt;
                                        &lt;/Trigger&gt;
                                &lt;/ControlTemplate.Triggers&gt;
                        &lt;/ControlTemplate&gt;
                &lt;/Setter.Value&gt;
        &lt;/Setter&gt;
&lt;/Style&gt;
</code></pre>
<p>使用方式如下:</p>
<p>效果图1:<br>
<img src="https://img2024.cnblogs.com/blog/2212230/202507/2212230-20250710165222295-432797959.png"></p>
<p>效果图2:<br>
<img src="https://img2024.cnblogs.com/blog/2212230/202507/2212230-20250710165437100-1045629082.png"></p>
<p><strong>如果本文介绍对你有帮助,可以一键四连:点赞+评论+收藏+推荐,谢谢!</strong></p><br><br>
来源:https://www.cnblogs.com/chenshibao/p/18977257
頁: [1]
查看完整版本: WPF开发中重写Combox样式遇到的一些问题