Tengo un control ListBox y me estoy presentando un número fijo de ListBoxItem objetos en un diseño de cuadrícula. Así que me he puesto mi ItemsPanelTemplate a ser una Cuadrícula.

Yo estoy acceso a la red desde el código para configurar el elemento rowdefinitions y ColumnDefinitions.

Hasta ahora todo está funcionando como se esperaba. Tengo algunas personalizado IValueConverter implementaciones para la devolución de la Cuadrícula.De la fila y de la Cuadrícula.La columna que cada ListBoxItem debe aparecer en.

Sin embargo me extrañas pasan de unión de los errores a veces, y yo no puedo averiguar exactamente por qué está sucediendo, o incluso si está en mi código.

Aquí está el error:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ItemsControl', AncestorLevel='1''. BindingExpression:Path=HorizontalContentAlignment; DataItem=null; target element is 'ListBoxItem' (Name=''); target property is 'HorizontalContentAlignment' (type 'HorizontalAlignment')

¿Alguien puede explicar qué está pasando?

Ah, aquí está mi XAML:

<UserControl.Resources>
<!-- Value Converters -->
<v:GridRowConverter x:Key="GridRowConverter" />
<v:GridColumnConverter x:Key="GridColumnConverter" />
<v:DevicePositionConverter x:Key="DevicePositionConverter" />
<v:DeviceBackgroundConverter x:Key="DeviceBackgroundConverter" />
<Style x:Key="DeviceContainerStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Grid.Row" Value="{Binding Path=DeviceId, Converter={StaticResource GridRowConverter}}" />
<Setter Property="Grid.Column" Value="{Binding Path=DeviceId, Converter={StaticResource GridColumnConverter}}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border CornerRadius="2" BorderThickness="1" BorderBrush="White" Margin="2" Name="Bd"
Background="{Binding Converter={StaticResource DeviceBackgroundConverter}}">
<TextBlock FontSize="12" HorizontalAlignment="Center" VerticalAlignment="Center" 
Text="{Binding Path=DeviceId, Converter={StaticResource DevicePositionConverter}}" >
<TextBlock.LayoutTransform>
<RotateTransform Angle="270" />
</TextBlock.LayoutTransform>
</TextBlock>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="Bd" Property="BorderThickness" Value="2" />
<Setter TargetName="Bd" Property="Margin" Value="1" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>            
</Style>        
</UserControl.Resources>
<Border CornerRadius="3" BorderThickness="3" Background="#FF333333" BorderBrush="#FF333333" >
<Grid ShowGridLines="False">
<Grid.RowDefinitions>
<RowDefinition Height="15" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal">
<Image Margin="20,3,3,3" Source="Barcode.GIF" Width="60" Stretch="Fill" />
</StackPanel>
<ListBox ItemsSource="{Binding}" x:Name="lstDevices" Grid.Row="1" 
ItemContainerStyle="{StaticResource DeviceContainerStyle}"
Background="#FF333333"
SelectedItem="{Binding SelectedDeviceResult, ElementName=root, Mode=TwoWay}" >
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<Grid>
<Grid.LayoutTransform>
<RotateTransform Angle="90" />
</Grid.LayoutTransform>                            
</Grid>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
</Grid>
</Border>

  • Me da el mismo error cuando estoy filtrado de una lista en tiempo de ejecución.

12 Comentarios

  1. 30

    La unión problema viene desde el estilo predeterminado para ListBoxItem. Por defecto, cuando la aplicación de estilos a los elementos de WPF busca los estilos por defecto y se aplica cada propiedad que no esté específicamente establecido en el estilo personalizado desde el estilo predeterminado. Consulte este gran blog Por Ian Griffiths para más detalles sobre este comportamiento.

    De vuelta a nuestro problema. Aquí es el estilo por defecto de ListBoxItem:

    <Style
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:s="clr-namespace:System;assembly=mscorlib"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    TargetType="{x:Type ListBoxItem}">
    <Style.Resources>
    <ResourceDictionary/>
    </Style.Resources>
    <Setter Property="Panel.Background">
    <Setter.Value>
    <SolidColorBrush>
    #00FFFFFF
    </SolidColorBrush>
    </Setter.Value>
    </Setter>
    <Setter Property="Control.HorizontalContentAlignment">
    <Setter.Value>
    <Binding Path="HorizontalContentAlignment" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=ItemsControl, AncestorLevel=1}"/>
    </Setter.Value>
    </Setter>
    <Setter Property="Control.VerticalContentAlignment">
    <Setter.Value>
    <Binding Path="VerticalContentAlignment" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=ItemsControl, AncestorLevel=1}"/>
    </Setter.Value>
    </Setter>
    <Setter Property="Control.Padding">
    <Setter.Value>
    <Thickness>
    2,0,0,0
    </Thickness>
    </Setter.Value>
    </Setter>
    <Setter Property="Control.Template">
    <Setter.Value>
    <ControlTemplate TargetType="{x:Type ListBoxItem}">
    ...
    </ControlTemplate>
    </Setter.Value>
    </Setter>
    </Style>

    Nota que me han quitado el ControlTemplate para que quede compacto (yo he usado StyleSnooper – para recuperar el estilo). Usted puede ver que hay un enlace con un pariente origen del antepasado con el tipo ItemsControl. Así que, en su caso, el ListBoxItems que se crean cuando la unión no encontrar su ItemsControl. Puedes dar más información de lo que es la ItemsSource para su ListBox?

    P. S.: Una forma de eliminar los errores es crear nuevas incubadoras para HorizontalContentAlignment y VerticalContentAlignment en su Estilo personalizado.

    • +1, aunque sólo sea por el enlace a StyleSnooper 🙂
    • +1 para el puntero a Ian Griffith post. Que es manos abajo, una de las mejores descripciones sobre cómo obtener elementos de estilo … que he leído jamás.
    • Además, tener un setter para HorizontalContentAlignment en mi Estilo personalizado, NO parece hacer una diferencia para mí (esto es para un ComboBoxItem aunque).
    • +1 para el conjunto de la respuesta, debe marcar la respuesta correcta, a mi me funciono perfectamente
    • Traté de configuración HorizontalContentAlignment, VerticalContentAlignment, HorizontalAlignment, y VerticalAlignment para mi ListBoxItem estilo y fracasó. Creo que tiene que ver con la interacción entre el ListBoxItem y la ControlTemplate del scrollviewer.
  2. 22

    Configuración OverridesDefaultStyle a True en su ItemContainerStyle también de solucionar estos problemas.

    <Style TargetType="ListBoxItem">
    <Setter Property="OverridesDefaultStyle" Value="True"/>
    <!-- set the rest of your setters, including Template, here -->
    </Style>
    • Cierto, pero también provocó mi elemento no se presente a sí mismo correctamente. Asegúrese de que si usted hace esto, usted tiene bastante de el estilo especificado que no necesita nada de la predeterminada (consulte @ligaz de la respuesta anterior)
    • ayuda; yo lo hice para mi CustromTreeViewItem objeto y no tengo más excepciones como las que se describen
    • Este solucionado un problema que me tenía así. En nuestros controles son completamente re-styling de ellos, por lo que no desea que el estilo por defecto usa de todos modos. Ni siquiera sabía acerca de esta propiedad de Estilo. Gracias!
    • +1 para mí funcionaba perfectamente bien
    • Esto oculta mi lista de elementos. Para resolver, agregar BasedOn="{StaticResource {x:Type ListBoxItem}}" a su style, justo después de TargetType="ListBoxItem". Yo estaba usando un custom VirtualizingWrapPanel.
  3. 7

    Este es un problema común con ListBoxItems y otros efímeros *Item contenedores. Se crean de forma asincrónica/sobre la marcha, mientras que el ItemsControl se carga/prestados. Usted tiene que adjuntar a ListBox.ItemContainerGenerator‘s StatusChanged evento y esperar a que el Estado convertido en ItemsGenerated antes de intentar acceder a ellos.

    • ¿Puede explicar esto? Yo creo que este es mi problema. Estoy intentando enlazar propiedad IsSelected a mi ListBoxItem a través de estilo, pero a causa de esta excepción grupo de selecciones no se desplazará como se esperaba al ListBox.SelectionMode=Extendida. Cómo se podría ir sobre la interceptación de la comunicación entre el IsSelected Elemento y tener que esperar para el StatusChanged evento para terminar la cocción?
  4. 6

    Esta es una amalgama de las otras respuestas aquí, pero para mí, he tenido que aplicar el Setter en dos lugares para solucionar el error, aunque esto fue cuando se utiliza una costumbre VirtualizingWrapPanel

    Si puedo eliminar uno de los siguientes Setter declaraciones, mis errores a aparecer.

            <ListView>
    <ListView.Resources>
    <Style TargetType="ListViewItem">
    <Setter Property="HorizontalContentAlignment" Value="Left" />
    <Setter Property="VerticalContentAlignment" Value="Top" />
    </Style>
    </ListView.Resources>
    <ListView.ItemContainerStyle>
    <Style TargetType="ListViewItem">
    <Setter Property="HorizontalContentAlignment" Value="Left" />
    <Setter Property="VerticalContentAlignment" Value="Top" />
    </Style>
    </ListView.ItemContainerStyle>
    <ListView.ItemsPanel>
    <ItemsPanelTemplate>
    <controls:VirtualizingWrapPanel />
    </ItemsPanelTemplate>
    </ListView.ItemsPanel>
    </ListView>

    Realmente no tienen el tiempo para investigar más a fondo en el momento, pero sospecho que tiene que ver con el estilo por defecto que JTango menciona en su respuesta – realmente no estoy personalizando mi plantilla a un enorme grado.

    Creo que hay más distancia que se tenía de las otras respuestas, pero yo pensé que había puesto esta en la posibilidad de ayuda a alguien en el mismo barco.

    David Schmitt, la respuesta parece podría describir la causa raíz.

    • Deberíamos haber estado usando el mismo VirtualizingWrapPanel y es «diferente» de alguna manera y hace que el problema ligeramente variated. La adición de BasedOn="{StaticResource {x:Type ListBoxItem}}" para Style y <Setter Property="OverridesDefaultStyle" Value="True"/> bajo Style, de ListView.ItemContainerStyle también ayuda.
    • Buena sugerencia, parece que hay algunas sutilezas de entender.
  5. 3

    Yo tenía el mismo problema que tú y yo sólo quería compartir lo que fue mi solución.
    He intentado todas las opciones de este post, pero la última fue la mejor para mí – thx Chris.

    Así que mi código:

    <ListBox.Resources>
    <Style x:Key="listBoxItemStyle" TargetType="ListBoxItem">
    <Setter Property="HorizontalContentAlignment" Value="Center" />
    <Setter Property="VerticalContentAlignment" Value="Center" />
    <Setter Property="MinWidth" Value="24"/>
    <Setter Property="IsEnabled" Value="{Binding IsEnabled}"/>
    </Style>
    <Style TargetType="ListBoxItem" BasedOn="{StaticResource listBoxItemStyle}"/>
    </ListBox.Resources>
    <ListBox.ItemContainerStyle>
    <Binding Source="{StaticResource listBoxItemStyle}"/>
    </ListBox.ItemContainerStyle>
    <ListBox.ItemsPanel>
    <ItemsPanelTemplate>
    <WrapPanel Orientation="Horizontal" IsItemsHost="True" MaxWidth="170"/>
    </ItemsPanelTemplate>
    </ListBox.ItemsPanel>

    También he descubierto que este error no aparecen cuando personalizado ItemsPanelTemplate no existe.

  6. 2

    Acabo encontrado con el mismo tipo de error:

    Sistema.Windows.Error De Datos: 4 :
    No se puede encontrar la fuente para el enlace con la referencia
    ‘RelativeSource FindAncestor, AncestorType=’Sistema.Windows.Controles.ItemsControl’, AncestorLevel=’1″.
    BindingExpression:Path=HorizontalContentAlignment;
    DataItem=null; elemento de destino es «ListBoxItem’ (Nombre=»);
    objetivo de la propiedad es ‘HorizontalContentAlignment’ (tipo «HorizontalAlignment’)

    Esto sucedió mientras se hace un enlace como este:

    <ListBox ItemsSource="{Binding Path=MyListProperty}"  />

    A esta propiedad en mi contexto de datos de objeto:

    public IList<ListBoxItem> MyListProperty{ get; set;}

    Después de algunos experimentos, descubrí que el error se activa sólo cuando el número de elementos supera la altura visible de mi ListBox (por ejemplo, cuando aparece una barra de desplazamiento vertical).
    Así que inmediatamente pensé acerca de la virtualización y probado esto:

    <ListBox ItemsSource="{Binding Path=MyListProperty}" VirtualizingStackPanel.IsVirtualizing="False" />

    Esta resuelto el problema para mí.
    Aunque yo prefiero mantener la virtualización de encendido no utilizo ningún más tiempo para bucear en ella.
    Mi aplicación es un poco en el complejo lado con varias niveles de mallas, acoplar los paneles etc. y algunos asynch llamadas de método.
    Yo no era capaz de reproducir el problema en una simple aplicación.

    • Esto soluciona mi problema. Supongo que los enlaces de fuego antes de que el elemento está completamente cargado. En mi opinión, esto es un error, y como tal he presentado con MSDN (aunque estoy seguro que no soy el primero) y publicado esto como una solución.
  7. 2

    Otra solución alternativa que trabajó para mí era suprimir estos errores (en realidad, parece más apropiado llamarlos advertencias) al establecer el enlace de datos de origen interruptor de nivel crítico en el constructor de la clase o una ventana de nivel superior –

    #if DEBUG     
    System.Diagnostics.PresentationTraceSources.DataBindingSource.Switch.Level =
    System.Diagnostics.SourceLevels.Critical;
    #endif

    Ref.: Cómo suprimir el Sistema.Windows.Datos de Error mensaje de advertencia

  8. 1

    De acuerdo a la Plantillas De Datos De Información General en MSDN, DataTemplates debe ser utilizado como la ItemTemplate para definir la forma en que se presentan los datos, mientras que un Style sería utilizado como el ItemContainerStyle al estilo de la que genera contenedor, como ListBoxItem.

    Sin embargo, parece que usted está tratando de utilizar este último para hacer el trabajo de la ex. Yo no puedo volver a la situación sin necesidad de mucho más código, pero sospecho que haciendo de enlace de datos en el contenedor de estilo podría ser lanzar una llave inglesa en el supuesto de visual/árbol lógico.

    También no puedo dejar de pensar que un diseño personalizado de artículos basados en el elemento de información de llamadas para crear una personalizada Panel. Es probablemente el mejor de la costumbre de Panel para el diseño de los elementos de los elementos para establecer ellos mismos con un Rube Goldberg surtido de IValueConverters.

  9. 1

    Si quieres reemplazar completamente la ListBoxItem plantilla tal que ninguna selección es visible (tal vez desea que el aspecto de ItemsControl con la agrupación de/etc comportamiento de ListBox), entonces usted puede utilizar este estilo:

    <Style TargetType="ListBoxItem">
    <Setter Property="Margin" Value="2" />
    <Setter Property="FocusVisualStyle" Value="{x:Null}" />
    <Setter Property="OverridesDefaultStyle" Value="True" />
    <Setter Property="Template">
    <Setter.Value>
    <ControlTemplate TargetType="{x:Type ListBoxItem}">
    <ContentPresenter Content="{TemplateBinding ContentControl.Content}" 
    HorizontalAlignment="Stretch" 
    VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}" 
    SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
    </ControlTemplate>
    </Setter.Value>
    </Setter>
    </Style>

    Esta plantilla también se excluye el estándar Border contenedor. Si usted necesita, puede usar reemplazar la plantilla con esto:

    <Border BorderThickness="{TemplateBinding Border.BorderThickness}" 
    Padding="{TemplateBinding Control.Padding}" 
    BorderBrush="{TemplateBinding Border.BorderBrush}" 
    Background="{TemplateBinding Panel.Background}" 
    SnapsToDevicePixels="True">
    <ContentPresenter Content="{TemplateBinding ContentControl.Content}" 
    ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}" 
    HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}" 
    VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}" 
    SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
    </Border>

    Si usted no necesita todas estas TemplateBinding valores, a continuación, puede eliminar algunos de rendimiento.

  10. 0

    Simplemente la creación de un estilo predeterminado para el tipo «ComboBoxItem» no funciona, porque es sobreescrito por el ComboBox predeterminado de «ItemContainerStyle». Realmente deshacerse de esto, usted necesita para cambiar el valor de «ItemContainerStyle» distintos para el mismo, como este:

    <Style TargetType="ComboBox">
    <Setter Property="ItemContainerStyle">
    <Setter.Value>                
    <Style TargetType="ComboBoxItem">
    <Setter Property="HorizontalContentAlignment" Value="Left" />
    <Setter Property="VerticalContentAlignment" Value="Center" />
    </Style>
    </Setter.Value>
    </Setter>
    </Style>
  11. 0

    Empecé a correr en este problema, a pesar de que mi ListBox tenía un Estilo y una ItemContainerStyle conjunto – y estos estilos nombrados ya había definido HorizontalContentAlignment. Yo estaba usando los controles CheckBox para activar/desactivar vivir filtrado en mi ListBox y esta parece ser la causa de los elementos de tirar de lugar desde el estilo por defecto en lugar de mi asignados estilos. La mayoría de los errores de los que produciría la primera vez que el vivir filtrado de patadas, pero a partir de entonces seguirá lanzar 2 errores en cada cambio. Me parece interesante que exactamente 2 de los registros en mi colección estaban vacías y por lo tanto no tenía nada que mostrar en el elemento. Por eso parece que han contribuyeron. I plan para crear datos por defecto que se mostrará cuando un registro está vacío.

    Sugerencia de Carter trabajó para mí. La adición de un independiente estilo «predeterminado» sin clave y un TargetType=»ListBoxItem» que define la HorizontalContentAlignment propiedad resuelto el problema. Ni siquiera necesitaba para establecer el OverridesDefaultStyle propiedad para ella.

Dejar respuesta

Please enter your comment!
Please enter your name here