2012-10-03 18 views
9

De acuerdo con this, la anulación del recurso ControlBrushKey debería cambiar el color de fondo de un elemento seleccionado de ListBox cuando no tiene foco. He creado un ejemplo sencillo para refutar esto:Anulando color de fondo de ListBoxItem cuando no está enfocado (.NET 4.5)

<StackPanel> 
    <ListBox> 
     <ListBox.Resources> 
     <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="LightBlue"/> 
     <!--SelectedItem without focus but doesn't really work--> 
     <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Orange" /> 
     </ListBox.Resources> 
     <ListBoxItem> 
     Item 1 
     </ListBoxItem> 
     <ListBoxItem> 
     Item 2 
     </ListBoxItem> 
    </ListBox> 
    <TextBox></TextBox> 
    </StackPanel> 

Si ejecuta esto en .NET 4.5 se puede ver que sólo cambia el color de enfoque, pero no la no-enfoque (que trabaja en. NET 4.0). ¿Alguna idea de por qué?

Editar: Esto parece ser un duplicado de List/Combo Box Background And Selected Colours Under .net 4.5.

+0

posible duplicado de [Lista/Fondo de cuadro combinado y colores seleccionados en .NET 4.5] (http://stackoverflow.com/questions/12007918/list-combo-box-background-and-selected-colours-under-net -4-5) –

Respuesta

1

Todo se trata del predeterminado templates de los controles, si no usan los colores del sistema como lo hicieron en .NET 4 esto simplemente no cambiará nada.

+0

¿No es eso un cambio radical? Y de todos modos parece que ControlBrushKey todavía se está utilizando. –

+0

@DoronYaacoby: No es un cambio radical porque confiar en cualquier cosa dentro de una plantilla de control es una tontería. Es un poco como invocar métodos privados a través de la reflexión. –

+0

Como esta es la respuesta aceptada y más votada para esta pregunta, supongo que mucha gente encontró que esta solución es la más simple, por lo que romperá muchas aplicaciones. Pero de todos modos, ¿cuál es la forma correcta de lograr lo que quiero? –

13

intente lo siguiente para cambiar el color de fondo de la ListBoxItem seleccionado cuando se ha perdido el foco:

XAML

<ListBox.Resources>  
    <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="LightBlue"/> 
    <SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey }" Color="Orange" />  
</ListBox.Resources> 

C#

listBox.Resources.Add(SystemColors.InactiveSelectionHighlightBrushKey, 
         new SolidColorBrush(Colors.Orange)); 

espero que funcione para usted.

+1

Consulte mi respuesta para obtener una solución que no implique cambiar SystemColors. – bugged87

-2

La solución a esto es la adición de

FrameworkCompatibilityPreferences.AreInactiveSelectionHighlightBrushKeysSupported = false; 

antes de llamar

InitializeComponent(); 
+0

Emite la excepción: "No se puede cambiar la propiedad 'AreInactiveSelectionHighlightBrush KeysSupported'. La clase 'FrameworkCompatibilityPreferences' se ha sellado." – bugged87

+0

@ bugged87 agrega esto dentro del bloque try/catch. Mis programas usan esto y todo parece como está previsto en todas las versiones de Windows – Daniel

+0

Claro, al agregar un try/catch maneja la excepción, pero este código no parece hacer que el código del OP funcione. Estoy usando .NET 4.5 en Windows 8.1. – bugged87

0

Esto es lo que ocurrió con que no implique cambio de colores del sistema o las plantillas de control. Simplemente ajuste el ListBox en un nuevo UserControl.

public partial class StyledListBox : UserControl 
{ 
    public DataTemplate ItemTemplate 
    { 
     get { return (DataTemplate)GetValue(ItemTemplateProperty); } 
     set { SetValue(ItemTemplateProperty, value); } 
    } 

    public IEnumerable ItemsSource 
    { 
     get { return (IEnumerable)GetValue(ItemsSourceProperty); } 
     set { SetValue(ItemsSourceProperty, value); } 
    } 

    public object SelectedItem 
    { 
     get { return GetValue(SelectedItemProperty); } 
     set { SetValue(SelectedItemProperty, value); } 
    } 

    public StyledListBox() 
    { 
     InitializeComponent(); 
    } 

    public static readonly DependencyProperty ItemTemplateProperty = DependencyProperty.Register("ItemTemplate", typeof(DataTemplate), typeof(StyledListBox), new FrameworkPropertyMetadata(null)); 
    public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(StyledListBox), new FrameworkPropertyMetadata(null)); 

    public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register("SelectedItem", typeof(object), typeof(StyledListBox), new FrameworkPropertyMetadata(null) 
    { 
     BindsTwoWayByDefault = true, 
     DefaultUpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged 
    }); 
} 

XAML:

<UserControl x:Class="StyledListBox" 

    <ListBox ItemsSource="{Binding ItemsSource, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type common:StyledListBox}}}" 
       SelectedItem="{Binding SelectedItem, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type common:StyledListBox}}}"> 

     <ListBox.ItemTemplate> 
      <DataTemplate> 
       <Border> 
        <Border.Style> 
         <Style TargetType="{x:Type Border}"> 
          <Style.Triggers> 
           <DataTrigger Binding="{Binding IsSelected, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}" 
              Value="True"> 
            <Setter Property="Background" Value="Red" /> 
           </DataTrigger> 
          </Style.Triggers> 
         </Style> 
        </Border.Style> 

        <ContentPresenter ContentTemplate="{Binding ItemTemplate, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type StyledListBox}}}" /> 
       </Border> 
      </DataTemplate> 
     </ListBox.ItemTemplate> 
    </ListBox> 
</UserControl> 

A continuación, basta con utilizar el control de usuario envoltorio como si se tratara de un cuadro de lista. Cualquier otra propiedad de ListBox que desee controlar simplemente puede agregarse al contenedor de la misma manera que ItemsSource y SelectedItem de mi ejemplo.

Cuestiones relacionadas