views:

53

answers:

3

I want to have a combobox with dropdown list of codes and definitions, but only display the definition of the selected item in the textbox part. For example, Y-Yes and N-No in the dropdown, and when Y is selected, only display Yes in the textbox.

A: 

If you are using WPF to do this, use Binding.

Say you bind a collection of a class :

public class Item
{
  public string Key{
    get 
    {
      return this.Value[0].ToString();
    }
  }
  public string Value{get;set;}
  public override string ToString()
  {
     return this.Key; 
  }
}

You can use it to show Key and Value as shown

<ComboBox x:Name="cmbList" ItemsSource="{Binding}" Text="{Binding SelectedItem.Value}"></ComboBox>

I hope this would help you in solving your problem.

abhishek
@abhishek He doesn't mean a separate textbox. He means the textbox part.
Avatar
Yes then it should be bound with Text property of the ComboBox.
abhishek
A: 

You should use SelectValuePath and DisplayMemberPath.

Avatar
Avatar, Can you give me an example of how to use these?
Gerry
A: 

Possible duplicate of this post

Anyway, a solution to your problem.

Say you have this class

public class CodeAndDefinition
{
    public CodeAndDefinition(string code, string definition)
    {
        Code = code;
        Definition = definition;
    }

    public string Code
    {
        get;
        set;
    }
    public string Definition
    {
        get;
        set;
    }
    public string MergedCodeAndDefinition
    {
        get
        {
            return Code + "-" + Definition;
        }
    }
}

and then you create some List and set the DataContext on the ComboBox.

CodeAndDefinitions = new List<CodeAndDefinition>();
CodeAndDefinitions.Add(new CodeAndDefinition("Y", "Yes"));
CodeAndDefinitions.Add(new CodeAndDefinition("N", "No"));
CodeAndDefinitions.Add(new CodeAndDefinition("M", "Maybe"));
c_comboBox.DataContext = CodeAndDefinitions;

Then you can use a ComboBox like this to get the desired behavior.

<Window.Resources>
    <SolidColorBrush x:Key="SelectedBackgroundBrush" Color="#DDD" />
    <SolidColorBrush x:Key="DisabledForegroundBrush" Color="#888" />

    <ControlTemplate x:Key="MergedDescriptionTemplate" TargetType="ComboBoxItem">
        <Border Name="Border" Padding="2" SnapsToDevicePixels="true">
            <TextBlock Text="{Binding Path=MergedCodeAndDefinition}"/>
        </Border>
        <ControlTemplate.Triggers>
            <Trigger Property="IsHighlighted" Value="true">
                <Setter TargetName="Border" Property="Background" Value="{StaticResource SelectedBackgroundBrush}"/>
            </Trigger>
            <Trigger Property="IsEnabled" Value="false">
                <Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/>
            </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>
</Window.Resources>
<Grid>
    <ComboBox Name="c_comboBox" ItemsSource="{Binding}" SelectedIndex="0" Height="25" Width="200">
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Path=Definition}"/>
            </DataTemplate>
        </ComboBox.ItemTemplate>
        <ComboBox.ItemContainerStyle>
            <Style TargetType="{x:Type ComboBoxItem}">
                <Setter Property="Template" Value="{StaticResource MergedDescriptionTemplate}" />
            </Style>
        </ComboBox.ItemContainerStyle>
    </ComboBox>
</Grid>

UPDATE

If I understood your comment correctly than this is what you need instead. Just remove the

<ComboBox.ItemContainerStyle>
    <Style TargetType="{x:Type ComboBoxItem}">
        <Setter Property="Template" Value="{StaticResource MergedDescriptionTemplate}" />
    </Style>
</ComboBox.ItemContainerStyle>

and add

<Style x:Key="{x:Type ComboBoxItem}" TargetType="ComboBoxItem">
    <Setter Property="SnapsToDevicePixels" Value="true"/>
    <Setter Property="OverridesDefaultStyle" Value="true"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ComboBoxItem">
                <Border Name="Border" Padding="2" SnapsToDevicePixels="true">
                    <TextBlock Text="{Binding Path=MergedCodeAndDefinition}"/>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsHighlighted" Value="true">
                        <Setter TargetName="Border" Property="Background" Value="{StaticResource SelectedBackgroundBrush}"/>
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

If the resource where you put this in is included for every xaml file than this style will apply to all ComboBoxItem's.

Meleak
Meleak, Thank you for your help. However, I don't think I can bind to anything static. I have hundreds of Comboboxes defined in XAML files which are loaded into memory. I want all of them to work the same way. They all have the same format: 'Id-Description'. I need the dropdown part to show 'Id-Description' and the textbox part to show 'Description'. I was hoping there was a way to alter the behavior of all comboboxes this way, as a setting in the combobox Xaml for each field, or a systemwide setting, or to handle it somehow in the c# screen I/O program when displaying any combobox.
Gerry