2009-07-10 21 views
5

データテンプレートを使用して、ComboBoxの一部のアイテムを視覚化します。 ItemsSourceはObservableCollectionにバインドされています。 のは、私がのObservableCollectionに人物を入れたとしましょう、それをシンプルに保つために:DataTemplateを使用してWPF-ComboBoxItemのTextSearch.Textを設定します。

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

私のDataTemplateは次のようになります。

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

今、私は導入せずに、コンボボックス内の完全名の自動補完を有効にします私の人のクラスの3番目のプロパティ。したがって、私はComboBoxでTextSearch.TextPathプロパティを使用するのではなく、代わりにDataTemplateの各ComboBoxItemのTextSearch.Text-Propertyをバインドしたいと思います。 残念なことに、私がこれを行うと(これはMultiBindingとStringFormatで動作し、Snoopでテストされています)、バインドされた値はStackPanelにのみ登録されますが、Snoop(素晴らしいツール)を使用してこのスタックパネルは、 ComboBoxItemTemplateは、別の境界線などを置き、最後にComboBoxItemタグを外側のStackPanelの周りに配置します。したがって、TextSearch.Text設定は、作成されたComboBoxItemに設定されていなければならないため、有効ではありません。

Question Now: XAMLスタイルと-Control-Templatesのみを使用して、このTextSearch.TextプロパティをDataTemplateから周囲のComboBoxItemに伝播するにはどうすればよいですか? 解決策は、ComboBoxとComboBoxItemのデフォルトのControlTemplateとカスタム(Item-)DataTemplateを変更できますが、コードビハインドは使用しないでください。おそらく付随する行動も大丈夫だろう。しかし、私は、TemplateBindingまたはRelativeSource-stuffなしで動作させる方法がなければならないとほとんど確信しています。 もちろん、ソリューションでは、キーボード選択とテキストコンプリートを行う必要があります。リストにハンス・ジョセフとハンス・ピーターが含まれているときは、ハンス・ジョセフを自動尋問するべきです。

すべてのソリューションはありますか?

+0

少なくとも今私はかなり自信を持っています。その作業は実際にはあまり簡単ではありません。または、長いテキストは人々をパニックに逃げさせているだけです... –

+0

私はそれをあきらめているのです。 ComboBoxItemをComboBox.ItemContainerStyle(ItemTemplateの代わりに、これまでのように)で設定して、正しいTextSearch.Text-Propertyを運ぶようにしました。 これはビジュアルツリー(Snoop again)でかなりうまく見えますが、残念ながらそれは何の効果もありません。 'Hans'などの入力後に選択が行われません。 –

答えて

1

パネルを囲むものがデフォルトのコンテナです。 TextSearch.Textプロパティをコンテナに適用する必要があります。あなたはそのようItemContainerStyleを経由してプロパティを設定することによってこれを行うことができるようになります。

<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

完全に妥当な音ですが、残念ながらうまくいきません。 キーボードの選択は望ましくないように動作します。入力が人間のToString値と比較されている場合、textsearch.textはまったく効果がありません。 私はバインディングが動作すると思いますが、ComboBoxはそれを無視します。 –

+0

私のために働いていないあなたはこのTextSearch.Textをスタイル – Hisham

8

短い答え:あなたはXAMLで直接実行することはできませんやりたいが、それを行うには、他の方法がある何か。

長い回答:ComboBoxはItemsSourceコレクションに格納されているデータ項目のTextSearch.Textプロパティを直接検索します。したがって、データ項目またはデータ項目は、データ項目自体ではなく、データ項目を表示するために使用されるオブジェクトに適用されるため、プロパティを設定することはできません。

特に、TextSearch classページの例を見ると、ComboBox.Itemsコレクションに入るImageオブジェクトにTextSearch.Textプロパティが付加されていることがわかります。あなたはPerson DependencyObjectを作ることであなたのプログラムでこれを行うことができますが、そのようなオブジェクトごとにプロパティを設定したくないと思います。

あなたがここにいくつかのオプションがあります。

あなたはPersonクラスを変更することができれば、あなたは上の自動補完やフルネームなどの任意のプロパティを定義し、Textsearch.TextPathを設定するテキストを返すために、toString()メソッドを定義しますかComboBoxでたとえば:あなたは人に触れることをしたくない場合は

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

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

Altenatively、あなたはこれらのプロパティを公開するラッパークラスを作成することができます。

+2

からターゲットできません。私はあなたが正しいと恐れています。今では、クラスに追加のプロパティを追加したり、新しいクラスをラップして拡張したりすることなく、実際のソリューションはありません。 これらの可能性は知られていますが、望んでいないことが質問で分かりましたので、私はこれを答えとすることはできません。 –

関連する問題