/ / Set TextSearch.Text pre WPF-ComboBoxItem cez DataTemplate - c #, wpf, dátové viazanie, combobox, datatemplate

Nastavte TextSearch.Text pre WPF-ComboBoxItem cez DataTemplate - c #, wpf, dátové viazanie, combobox, datatemplate

Používam datatemplate na vizualizáciu niektorých položiek v ComboBoxe, ItemSource je viazaný na ObservableCollection. Aby to bolo jednoduché, povedzme, že do pozorovateľnej kolekcie vložím osoby:

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

Moja DataTemplate vyzerá takto:

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

Teraz chcem povoliť úplné dopĺňaniemená v ComboBoxe bez toho, aby ste do triedy mojej osoby zaviedli tretiu vlastnosť. Preto nechcem používať vlastnosť TextSearch.TextPath na ComboBoxe, ale namiesto toho by som chcel viazať TextSearch.Text-Property každého ComboBoxItem v DataTemplate. Bohužiaľ, keď to urobím (čo funguje s MultiBinding a StringFormat, testované pomocou Snoop), je viazaná hodnota zaregistrovaná iba pre môj StackPanel, ale pomocou Snoop (skvelý nástroj) som zistila, že tento stackpanel slúži rovnako ako obsah pre niektoré ďalšie ComboBoxItemTemplate , čo kladie ďalšie hranice atď. a nakoniec značku ComboBoxItem okolo môjho vonkajšieho StackPanel. Preto nastavenie TextSearch.Text nie je účinné, pretože musí byť nastavené vo vytvorenom ComboBoxItem a nie niekde v ňom.

Otázka: Ako môžem propagovať toto vyhľadávanie textu.Textová vlastnosť z môjho DataTemplate do okolitého ComboBoxItem iba pomocou štýlov XAML a -Control-Templates? Riešenie môže modifikovať predvolené kontrolné šablóny ComboBox a ComboBoxItem a moje vlastné (Item-) DataTemplate, ale nesmie používať žiadny kódový kód alebo aspoň nie príliš veľa. Možno by bolo v poriadku aj pripútané správanie. Ale som si takmer istý, že musí existovať spôsob, ako to fungovať bez šablónových väzieb alebo zdrojov RelativeSource ... Riešenie samozrejme musí fungovať tak, že môj výber klávesnice a dokončovanie textu budú fungovať, s.th. ak zoznam obsahuje Hans Josef a Hans Peter, potom zadanie „Hans“ by malo automaticky podať žiadosť Hans Josef, zatiaľ čo zadanie „Hans P“ by malo dostatočne rýchlo podať automaticky Hans Peter.

Akékoľvek riešenia?

odpovede:

1 pre odpoveď č. 1

To, čo obklopuje váš panel, je predvolenékontajner. Na kontajner musíte použiť vlastnosť TextSearch.Text. Mali by ste to urobiť nastavením vlastnosti prostredníctvom ItemContainerStyle takto:

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

8 pre odpoveď č. 2

Stručná odpoveď: to, čo chcete urobiť, sa nedá urobiť priamo v XAML, existujú však aj iné spôsoby.

Dlhá odpoveď: ComboBox vyhľadá vlastnosť TextSearch.Text priamo na údajových položkách uložených v kolekcii Položky alebo Položky zdroja. Preto nemôžete nastaviť vlastnosť v dátovej šablóne alebo štýle, pretože sa vzťahujú na objekty používané na zobrazenie údajových položiek, a nie na samotné údajové položky.

Najmä ak sa pozriete na príklady na internete Trieda TextSearch uvidíte, že pripojiliVlastnosť TextSearch.Text pre objekty Image, ktoré idú do kolekcie ComboBox.Items. Môžete to urobiť vo svojom programe tak, že z Person urobíte DependencyObject, ale nemyslím si, že by ste chceli nastaviť vlastnosť na každý takýto objekt.

Máte tu niekoľko možností:

Ak môžete zmeniť triedu Person, môžetebuď definujte metódu ToString () na vrátenie textu na automatické doplňovanie alebo definujte ľubovoľnú vlastnosť, napríklad celé meno, a nastavte ComboBox na Textsearch.TextPath. Napríklad:

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

a

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

Ak sa nechcete dotknúť osoby, môžete vytvoriť alternatívu triedu obálok, ktorá odhaľuje tieto vlastnosti.