简体   繁体   中英

Define ComboBox' DataTemplate for TextBox (and define search pattern) when IsEditable is True?

I have a ComboBox whose ItemsSource is binding to a collection and the SelectedItem is binding to the properties of my VieModel . Let's call the binding properties AvailableOptions and TargetOption in ViewModel . And type of collection item and TargetOption is called MyOption . I have such requirements but I don't know how to fulfill them all:

  1. It should be OK for the binding TargetOption to have NULL as value
  2. I want to set a DataTemplate for the target type in TargetOption collection to be displayed in the ComboBox
  3. If possible, I want use different DataTemplate for MyOption when then are in the drop-down of ComboBox and when one item is selected. Because my UserControl has limited space so it should be compact when item is selected and during the selection it should provide more information

As I said, I don't know how to do all of them. At first I have the XAML like this:

<ComboBox SelectedItem="{Binding SelectedOption} ItemsSource="{Binding AvailableOptions}" >                          
    <ComboBox.ItemTemplateSelector>
        <MyNameSpace:ComboBoxItemTemplateSelector ItemTemplate="{StaticResource OptionDetailTemplate}" SelectedItemTemplate="{StaticResource OptionSimpleTemplate}" />
    </ComboBox.ItemTemplateSelector>
</ComboBox>

With a customized ItemTemplateSelector . I am able to do the requirement 2) and 3). My OptionDetailTemplate looks like this:

<DataTemplate x:Key="OptionDetailTemplate">
    <StackPanel Orientation="Horizontal">
        <TextBlock Text="{Binding ShortName}" />
        <TextBlock Text=" | " />
        <TextBlock Text="{Binding Code}" />
    </StackPanel>
</DataTemplate>

and OptionSimpleTemplate looks like this:

<DataTemplate x:Key="OptionSimpleTemplate">
    <StackPanel Orientation="Horizontal">
        <TextBlock Text="{Binding ShortName}" />
        <TextBlock Text=" | " />
        <TextBlock Text="{Binding Code}" />
        <TextBlock Text=" | " />
        <TextBlock Text="{Binding Number}" />
    </StackPanel>
</DataTemplate>

But now the problem is requirement 1). When the user select one option from the drop down list of the ComboBox , he can't put it as NULL back which should be allowed. This is because AvailableOption doesn't have a NULL object

I see that if I set IsEditable to True for the ComboBox , and set TextSearch.TextPath to Code , it allows the text quick search/assign and also allows to have a NULL value when the search text is totally deleted. But now when I ever select one, it only displays Code (the OptionTemplate does not have any effect any more because now it displays the selected item in a TextBox ). This is not good since only Code is not enough for the user to tell what Option it is. But since I have multiple properties in MyOption class, how can I define the DataTemplate for the TextBox and also define the search routine?

I have to be honest that I didn't fully understand your first requirement and its ramifications. however, I am really just answering to let you know that you don't even need to use a DataTemplateSelector to select between your two DataTemplate s. If you do not set the x:Key value on them, then they will be applied to the relevant items implicitly:

<DataTemplate DataType="{x:Type YourXamlNamespacePrefix:TargetOption}">
    <StackPanel Orientation="Horizontal">
        <TextBlock Text="{Binding ShortName}" />
        <TextBlock Text=" | " />
        <TextBlock Text="{Binding Code}" />
    </StackPanel>
</DataTemplate>

...

<DataTemplate DataType="{x:Type YourXamlNamespacePrefix:MyOption}">
    <StackPanel Orientation="Horizontal">
        <TextBlock Text="{Binding ShortName}" />
        <TextBlock Text=" | " />
        <TextBlock Text="{Binding Code}" />
        <TextBlock Text=" | " />
        <TextBlock Text="{Binding Number}" />
    </StackPanel>
</DataTemplate>

Furthermore, you could do all this data binding with just a single TextBlock if you use a MultiDataTrigger :

<TextBlock>
    <TextBlock.Text>
        <MultiBinding StringFormat="{}{0}|{1}">
            <Binding Path="ShortName" />
            <Binding Path="Code" />
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>

Perhaps if you try clarifying your remaining problem (in your question), I might understand?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM