简体   繁体   English

覆盖默认 ComboBoxItem colors

[英]Override default ComboBoxItem colors

This works to override ComboBoxItem background colors in a Xamarin Forms WPF app, but isn't very elegant because I'm having to apply templates manually to ComboBoxItems in a custom renderer: This works to override ComboBoxItem background colors in a Xamarin Forms WPF app, but isn't very elegant because I'm having to apply templates manually to ComboBoxItems in a custom renderer:

App.xaml in Application.Resources: 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>

In Custom PickerRenderer:在自定义 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;
            }
        }
    }

I can't do the below though or I will get the following Exception:我不能执行以下操作,否则我会得到以下异常:

ArgumentException: Item has already been added. ArgumentException:已添加项目。 Key in dictionary: 'System.Windows.Controls.ComboBoxItem' Key being added: 'System.Windows.Controls.ComboBoxItem'字典中的键:'System.Windows.Controls.ComboBoxItem' 添加键:'System.Windows.Controls.ComboBoxItem'

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

or this, the defaults will not be overridden:或者这个,默认值不会被覆盖:

    <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>

Is there an easier and more elegant way to do what I want to do here?有没有更简单、更优雅的方式来做我想做的事情?

If you want to set the default comBoxItem template in the entire application to be customComboxItem.如果您想将整个应用程序中的默认comBoxItem 模板设置为customComboxItem。 You just put the style resource in app.xaml.您只需将样式资源放在 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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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