Переопределить цвета элементов списка по умолчанию

#c# #wpf #xaml #xamarin

#c# #wpf #xaml #xamarin

Вопрос:

Это работает для переопределения цветов фона элементов со списком в приложении Xamarin Forms WPF, но не очень элегантно, потому что мне приходится вручную применять шаблоны к элементам со списком в пользовательском средстве визуализации:

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.Элементы управления.Добавляется ключ элемента списка: ‘System.Windows.Элементы управления.Элемент списка списков ‘

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

Есть ли более простой и элегантный способ сделать то, что я хочу сделать здесь?

Ответ №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>
 

Комментарии:

1. Принимая это как ответ. У меня было место в моем коде в PickerRenderer OnElementChanged, где Contrtol . Использовался ItemContainerStyle, что и вызывало приложение. Стили ресурсов не должны применяться.