【问题标题】:Override default ComboBoxItem colors覆盖默认的 ComboBoxItem 颜色
【发布时间】:2020-12-13 07:06:04
【问题描述】:

这可以在 Xamarin Forms WPF 应用程序中覆盖 ComboBoxItem 背景颜色,但不是很优雅,因为我必须在自定义渲染器中手动将模板应用到 ComboBoxItems:

Application.Resources 中的 App.xaml:

    <ControlTemplate TargetType="{x:Type ComboBoxItem}" x:Key="CustomComboBoxItem">
        <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>
              ... All the regular triggers here override with new colors ...
        </ControlTemplate.Triggers>
    </ControlTemplate>

    <Style TargetType="{x:Type ComboBoxItem}">
        <Setter Property='OverridesDefaultStyle' Value='True'/>
        <Setter Property="Template" Value="{StaticResource CustomComboBoxItem}">
        </Setter>
    </Style>

在自定义 PickerRenderer 中:

    protected override void UpdateNativeWidget()
    {
        base.UpdateNativeWidget();
        var c = Control;
        if (p == null)
        {
            template = System.Windows.Application.Current.Resources["CustomComboBoxItem"] as System.Windows.Controls.ControlTemplate;
            ItemsPresenter presenter = GetVisualChild<ItemsPresenter>(c);
            Popup p = VisualTreeHelper.GetChild(VisualTreeHelper.GetChild(c, 0), 0) as Popup;
            var a = (((((p.Child) as Decorator).Child as Border).Child as ScrollViewer).Content as System.Windows.Controls.Grid).Children;
            presenter = a[1] as ItemsPresenter;
            this.p = presenter;
            this.p.Loaded += Presenter_Loaded;
        }
    }

    ItemsPresenter p;
    ComboBoxItem[] items;
    System.Windows.Controls.ControlTemplate template;

    private void Presenter_Loaded(object sender, RoutedEventArgs e)
    {
        items = new ComboBoxItem[Control.ItemContainerGenerator.Items.Count];
        for(int i=0;i<items.Length;i++)
        {
            items[i] = Control.ItemContainerGenerator.ContainerFromIndex(i) as ComboBoxItem;
            if (template != null)
            {
                items[i].Template = template;
            }
        }
    }

我不能执行以下操作,否则我会得到以下异常:

ArgumentException:项目已添加。字典中的键:'System.Windows.Controls.ComboBoxItem' 正在添加的键:'System.Windows.Controls.ComboBoxItem'

    <ControlTemplate TargetType="{x:Type ComboBoxItem}" x:Key="{x:Type ComboBoxItem}">
    </ControlTemplate>

或者这样,默认值不会被覆盖:

    <ControlTemplate TargetType="{x:Type ComboBoxItem}" x:Key="CustomComboBoxItem">
    </ControlTemplate>

    <Style TargetType="{x:Type ComboBoxItem}" x:Key="{x:Type ComboBoxItem}">
        <Setter Property='OverridesDefaultStyle' Value='True'/>
        <Setter Property="Template" Value="{StaticResource CustomComboBoxItem}">
        </Setter>
    </Style>

有没有更简单、更优雅的方式来做我想做的事情?

【问题讨论】:

    标签: c# wpf xaml xamarin


    【解决方案1】:

    如果您想将整个应用程序中的默认comBoxItem模板设置为customComboxItem。 您只需将样式资源放在 app.xaml 中即可。

    <Application.Resources>
    <Style TargetType="{x:Type ComboBoxItem}" x:Key="{x:Type ComboBoxItem}">
        <Setter Property='OverridesDefaultStyle' Value='True'/>
        <Setter Property="Template" Value="{StaticResource CustomComboBoxItem}">
        </Setter>
    </Style>
    </Application.Resources>
    

    【讨论】:

    • 接受这个作为答案。我在代码中的 PickerRenderer OnElementChanged 中有一个位置,其中使用了 Contrtol.ItemContainerStyle,这就是导致 Application.Resources 样式不被应用的原因。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-27
    • 1970-01-01
    • 2014-07-21
    • 1970-01-01
    • 2021-08-23
    • 2022-01-12
    • 1970-01-01
    相关资源
    最近更新 更多