2009-07-10 26 views
5

Uso un datatemplate para visualizar algunos elementos en un ComboBox, ItemsSource está vinculado a un ObservableCollection. que sea sencillo, digamos que puse personas en el ObservableCollection:Establecer TextSearch.Text para WPF-ComboBoxItem a través de DataTemplate

public class Person { 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
} 

Mi DataTemplate se parece a esto:

<DataTemplate TargetType="{x:Type Person}"> 
    <StackPanel Orientation="Horizontal"> 
    <TextSearch.Text> 
     <MultiBinding StringFormat="{} {0} {1}"> 
     <Binding Path="FirstName"/> 
     <Binding Path="LastName"/> 
     </MultiBinding> 
    </TextSearch.Text> 
    <TextBlock Text="{Binding FirstName}" Margin="2,0" /> 
    <TextBlock Text="{Binding LastName}"/> 
    </StackPanel> 
</DataTemplate> 

Ahora desea habilitar el autocompletado de nombres completos en el cuadro combinado sin introducir una tercera propiedad en mi clase de persona. Por lo tanto, no quiero utilizar TextSearch.TextPath Property en el ComboBox, sino que me gustaría vincular el TextSearch.Text-Property de cada ComboBoxItem en el DataTemplate. Desafortunadamente, cuando hago esto (que funciona con un MultiBinding y StringFormat, probado con Snoop), el valor encuadernado se registra solo para mi StackPanel, pero al usar Snoop (gran herramienta) encontré que este stackpanel sirve como contenido para otros ComboBoxItemTemplate, que pone otro borde, etc. y finalmente una etiqueta ComboBoxItem alrededor de mi StackPanel externo. Por lo tanto, la configuración TextSearch.Text no es efectiva, porque debe establecerse en el ComboBoxItem creado, y no en algún lugar dentro.

Pregunta ahora: ¿Cómo puedo propagar este TextSearch.Text-Property desde mi DataTemplate al ComboBoxItem circundante usando XAML-Styles y -Control-Templates solamente? La solución puede modificar las Plantillas de control predeterminadas de ComboBox y ComboBoxItem y mi personalizada (Elemento) DataTemplate, pero no usar ningún código subyacente, o al menos no demasiado. Tal vez un comportamiento adjunto estaría bien, también. Pero estoy casi seguro de que debe haber una forma de hacerlo funcionar sin, TemplateBinding o RelativeSource-cosas ... Y, por supuesto, la solución debe hacer que mi selección de teclado y texto completen, en el s.th. cuando la lista contiene a Hans Josef y Hans Peter, entonces al ingresar a 'Hans' se debe autosugerir a Hans Josef, mientras que entrar a 'Hans P' con la suficiente rapidez debe autosuguar a Hans Peter.

¿Alguna solución?

+0

Al menos ahora me siento bastante seguro de que la tarea no es muy fácil. O el texto largo solo hace que la gente huya en pánico ... –

+0

Estoy a punto de abandonarlo. Logré hacer que ComboBoxItem llevara la TextSearch.Text-Property correcta configurándola en ComboBox.ItemContainerStyle (en lugar de ItemTemplate, como lo hice antes). Ahora se ve bastante bien en el árbol visual (Snoop otra vez), pero desafortunadamente no tiene ningún efecto. No hay selección teniendo lugar después de escribir 'Hans' o lo que sea. –

Respuesta

1

Lo que rodea su panel es el contenedor predeterminado. Debe aplicar la propiedad TextSearch.Text al contenedor. Usted debe ser capaz de hacer esto mediante el establecimiento de la propiedad a través de la ItemContainerStyle así:

<ComboBox.ItemContainerStyle> 
    <Style TargetType="{x:Type ComboBoxItem}"> 
     <Setter Property="TextSearch.Text"> 
      <Setter.Value> 
       <MultiBinding StringFormat="{} {0} {1}"> 
        <Binding Path="FirstName"/> 
        <Binding Path="LastName"/> 
       </MultiBinding> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</ComboBox.ItemContainerStyle> 
+0

Suena perfectamente razonable, pero desafortunadamente no funciona. La selección del teclado no se comporta como se desea, probablemente la entrada todavía se compara con el valor ToString de las personas, el textsearch.text no tiene ningún efecto. Supongo que el enlace funciona, pero el ComboBox lo ignora. –

+0

no funciona para mí, no puede orientar este TextSearch.Text desde el estilo – Hisham

8

Respuesta corta: lo que quiere hacer no se puede hacer directamente en XAML, pero hay otras maneras de hacerlo.

Respuesta larga: el ComboBox busca la propiedad TextSearch.Text directamente en los elementos de datos almacenados en la colección Items o ItemsSource. Por lo tanto, no puede establecer la propiedad en la plantilla o el estilo de datos porque se aplican a los objetos utilizados para mostrar los elementos de datos, y no a los elementos de datos mismos.

En particular, si mira los ejemplos en la página TextSearch class, verá que adjuntan la propiedad TextSearch.Text a los objetos de Imagen que entran en la colección ComboBox.Items. Puede hacer esto en su programa haciendo Person a DependencyObject, pero no creo que quiera establecer la propiedad en cada objeto de esa manera.

Usted tiene varias opciones aquí:

Si se puede modificar la clase persona, puede definir el método ToString() para devolver el texto a Autocompletar o definir una propiedad arbitraria como el nombre completo y establecer Textsearch.TextPath en el ComboBox.Por ejemplo:

public class Person 
{ 
    string FirstName { get; set; } 
    string LastName {get; set; } 
    string FullName { get { return String.Format("{0} {1}", FirstName, LastName); } } 
} 

y

<ComboBox TextSearch.TextPath="FullName" ItemsSource="collectionOfPersons"/> 

Altenatively, si no quieres tocar persona, puede crear una clase contenedora que expone estas propiedades.

+2

Me temo que tiene razón. Por ahora no hay una solución de trabajo sin agregar una propiedad adicional a la clase o incluso una nueva envoltura de clase y ampliar la anterior. Como la pregunta dice que estas posibilidades son conocidas pero no deseadas, no puedo marcar esto como _la_ respuesta - a menos que, si amplíe su respuesta corta mediante alguna prueba o explicación, por qué es imposible. –

Cuestiones relacionadas