2009-08-10 17 views
20

He estado luchando con este código desde hace algún tiempo y no puedo encontrar ninguna respuesta completa a mi pregunta. He creado una pequeña muestra para ilustrar el problema:¿El atributo de enlace de condición no funciona?

<ListView > 
    <ListView.ItemsPanel> 
     <ItemsPanelTemplate> 
     <StackPanel Margin="0,0,20,0" IsItemsHost="True" /> 
    </ItemsPanelTemplate> 
    </ListView.ItemsPanel> 
    <ListView.Items> 
     <TextBlock>Test1</TextBlock> 
     <TextBlock>Test2</TextBlock> 
     <TextBlock>Test3</TextBlock> 
     <TextBlock>Test4</TextBlock> 
     <TextBlock>Test5</TextBlock> 
    </ListView.Items> 
    <ListView.ItemContainerStyle> 
     <Style TargetType="{x:Type ListViewItem}"> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type ListViewItem}"> 
        <Grid> 
         <ContentPresenter/> 
        </Grid> 
        <ControlTemplate.Triggers> 
         <MultiTrigger> 
          <MultiTrigger.Conditions> 
           <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsMouseOver}" Value="True" /> 
           <Condition Property="IsSelected" Value="True"/> 
          </MultiTrigger.Conditions> 
          <Setter Property="Visibility" Value="Collapsed"/> 
         </MultiTrigger> 
        </ControlTemplate.Triggers> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
     </Style> 
    </ListView.ItemContainerStyle> 
</ListView> 

De acuerdo con la configuración MultiTrigger, el elemento seleccionado volverá a aparecer cuando el ratón no está sobre el elemento seleccionado. Sin embargo, este código produce una InvalidOperationException con el mensaje "Debe tener un valor no nulo para 'Property'". Si elimina la condición que utiliza el atributo "Enlace", la excepción no se produce. En la documentación de MSDN, indica que debe tener el atributo Propiedad o Enlace establecido. El código anterior funciona como el atributo de enlace no está configurado. De hecho, en todos mis casos de prueba, no importa en qué se establezca el atributo de enlace; la excepción todavía se arroja. ¿Alguna idea?

Respuesta

52

Este es uno de esos momentos en los que tienes que aguantar y admitir que has cometido un error absurdo. Sin embargo, para salvar a otro alma desafortunada de la misma suerte, revelaré mi epifanía.

En primer lugar, si había leído todo de la documentación hubiera leído la parte que dice si usted está utilizando "Encuadernación" atributo de la condición, que debe ser incluido en un elemento MultiDataTrigger (en lugar de la MutiTrigger elemento en mi ejemplo publicado).

En segundo lugar, al momento de realizar dichos cambios, el elemento MultiTrigger es reemplazar con el siguiente código:

<MultiDataTrigger> 
    <MultiDataTrigger.Conditions> 
     <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsMouseOver}" Value="True" /> 
     <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsSelected}" Value="True"/> 
    </MultiDataTrigger.Conditions> 
    <Setter Property="Visibility" Value="Collapsed"/> 
</MultiDataTrigger> 

Ahora el ejemplo funciona, pero debido a que el elemento seleccionado se derrumbó, la condición de activación avanza y retrocede haciendo que el seleccionado elemento para parpadear dentro y fuera de la vista. Tiene sentido, pero no es lo que pretendía.

¡De todos modos, espero que esto ayude a alguien a cometer el mismo error de bonehead!

+2

+1 Para admitir boneheadedness y dar una solución. Alguien más se encontrará con esto. Perder la palabra "Datos" es bastante fácil pasar por alto. –

+3

+1 Por llevarme a la solución mucho más rápido que buscar y leer la documentación. El error debería haber explicado esto en lugar de confiar en la documentación. – jpierson

+1

+1 Acabo de hacer el mismo movimiento tonto. Tu publicación probablemente me salvó una hora. –

3

En una nota muy similar, tirando de IsMouseOver de un borde como el contenido principal de la plantilla de datos, y tirando de IsSelected del Ancestro. Es interesante que ambas condiciones tengan una ruta relativa, supongo que la ruta predeterminada sería el contexto de datos local. Gracias por la solución anterior.

Código roto

<MultiDataTrigger> 
    <MultiDataTrigger.Conditions> 
     <Condition Binding="{Binding Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}, Path=IsSelected}" 
        Value="True" /> 
     <Condition SourceName="Border" 
        Property="IsMouseOver" 
        Value="True" /> 
    </MultiDataTrigger.Conditions> 
    <Setter TargetName="Border" 
      Property="Background" 
      Value="{StaticResource OnBrushSelected}" /> 
</MultiDataTrigger> 

Código de Trabajo

<MultiDataTrigger> 
    <MultiDataTrigger.Conditions> 
     <Condition Binding="{Binding Mode=OneWay, RelativeSource={RelativeSource Self}, Path=IsMouseOver}" 
        Value="True" /> 
     <Condition Binding="{Binding Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}, Path=IsSelected}" 
        Value="True" /> 
    </MultiDataTrigger.Conditions> 
    <Setter TargetName="Border" 
      Property="Background" 
      Value="{StaticResource OnBrushSelected}" /> 
</MultiDataTrigger> 
+0

Esto me ayudó, gracias. +1 – Dessus

+0

¡Quiero llamar a esto otro mito de WPF que no sigue ninguna convención! – mkb

Cuestiones relacionadas