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:
<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:
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. Key in dictionary: 'System.Windows.Controls.ComboBoxItem' Key being added: '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. You just put the style resource in 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>
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.