1

When I create a combobox in WPF I want it to have a name on it like "Your choice", just like if it was a common button and when I click on it I want only the items to dropdown, not the name on the combobox again. I hope you understand my question? Is there a way to solve this?

In the XAML I use this for the combobox:

<ComboBox Height="23" HorizontalAlignment="Left" Margin="110,226,0,0" Name="cmbChangeRoute" VerticalAlignment="Top" Width="156" SelectionChanged="cmbChangeRoute_SelectionChanged" />

And I add items in the C# code like this:

string[] strChangeRoute = new string[] { "Your choice", "10 deg", "20 deg", "30 deg" };
foreach (string s in strChangeRoute)
     cmbChangeRoute.Items.Add(s);
cmbChangeRoute.SelectedIndex = 0;
Martin Liversage
  • 104,481
  • 22
  • 209
  • 256
3D-kreativ
  • 9,053
  • 37
  • 102
  • 159
  • Why do you want the name of the combobox (= "Your choice") to disappear when the user clicks on it ? What if the user clicks on the comboxbox (making the name disappear), then directly clicks outside of it ? – franssu Aug 10 '12 at 08:55
  • are you trying overlay a label control over your combo box? – NoviceProgrammer Aug 10 '12 at 08:58
  • No, I don't want it to disappear, I just don't want it twice! As my code is now, I get the "Your choice" both on the "button" and also in inside the drop down items. – 3D-kreativ Aug 10 '12 at 09:01

5 Answers5

2

I would go for a TextBlock over the ComboBox who's visibility would be bound to the selectedItem of the ComboBox (through a converter).

<Grid>
    <ComboBox x:Name="myComboBox" />
    <TextBlock  Text="Your choice.." 
                IsHitTestVisible="False"
                Visibility="{Binding ElementName=myComboBox, Path=SelectedItem,
                  Converter={StaticResource yourChoiceLabelVisibilityConverter}}"/>
</Grid>

public class YourChoiceLabelVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter,
                          System.Globalization.CultureInfo culture)
    {
        if (value == null)
        {
            return Visibility.Visible;
        }

        return Visibility.Hidden;
    }

OR, a better solution : pure xaml, using triggers :

    <ContentControl x:Name="myContentControl" Content="{Binding}">
        <ContentControl.ContentTemplate>
            <DataTemplate>
                <Grid>
                    <ComboBox x:Name="myComboBox" ItemsSource="{Binding}"/>
                    <TextBlock x:Name="myTextBlock"
                               Text="Your choice.."
                               IsHitTestVisible="False"
                               Visibility="Hidden"/>
                </Grid>
                <DataTemplate.Triggers>
                    <Trigger SourceName="myComboBox" Property="SelectedItem"
                             Value="{x:Null}">
                        <Setter TargetName="myTextBlock" Property="Visibility
                                Value="Visible"/>
                    </Trigger>
                </DataTemplate.Triggers>
            </DataTemplate>
        </ContentControl.ContentTemplate>
    </ContentControl>

In this case don't forget to set your content control's datacontext from the codebehind :

myContentControl.DataContext = Enum.GetValues(typeof([YOUR ENUM]));
franssu
  • 2,422
  • 1
  • 20
  • 29
2

Try this, I just tested it

<ComboBox Height="23" HorizontalAlignment="Left" Margin="110,226,0,0" Name="cmbChangeRoute" VerticalAlignment="Top" Width="156" IsManipulationEnabled="False" IsEditable="True" Text="Your Choice..." SelectionChanged="cmbChangeRoute_SelectionChanged">
Clinton Ward
  • 2,441
  • 1
  • 22
  • 26
2

Have you tried using binding?

In XAML you have something like

<ComboBox ... SelectedItem="{Binding ChosenValue,Mode=TwoWay}" ... />

Then, in your constructor (in the code-behind) just add the line

this.DataContext = this;

So that your binding would actually look in the code-behind to find the dependency property ChosenValue. This way, every time the value in the combobox is changed, your prop's value would update to hold the currently selected item.

To achieve what you want, just set the prop's value to "Your Choice" in the constructor

public ClassName()
{
   InitializeComponent();
   this.DataContext = this;
   ChosenValue = "Your Choice";
}

Similarly, just set its value to the same string everywhere else you want. When saving or whatever, just check

if(!ChosenValue.Equals("Your Choice")
{
   //do logic
}
else
{
   //the user has not selected anything
}

Hope this helps!

quetzalcoatl
  • 32,194
  • 8
  • 68
  • 107
Ivan Petkov
  • 141
  • 6
2

What you want to do is actually not to configure the ComboBox, but to add an adorner/decorator over it, that would display a text while the Combo is closed, and that would hide itself when the combo is down. It sometimes is called "watermarking".

I will not explain it further, because it is pointless. Here's a nice article: http://pwlodek.blogspot.com/2009/11/watermark-effect-for-wpfs-textbox.html there's also all the code snippest required for watermarking the comboboxes.

quetzalcoatl
  • 32,194
  • 8
  • 68
  • 107
0

You can refer this one, How to display default text "--Select Team --" in combo box on pageload in WPF?

I would suggest the below solution from this forum,

you can do this without any code behind by using a IValueConverter.

<Grid>
   <ComboBox
       x:Name="comboBox1"
       ItemsSource="{Binding MyItemSource}"  />
   <TextBlock
       Visibility="{Binding SelectedItem, ElementName=comboBox1, Converter={StaticResource NullToVisibilityConverter}}"
       IsHitTestVisible="False"
       Text="... Select Team ..." />
</Grid>

Here you have the converter class that you can re-use.

public class NullToVisibilityConverter : IValueConverter
{
    #region Implementation of IValueConverter

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value == null ? Visibility.Visible : Visibility.Collapsed;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }

    #endregion
}

And finally, you need to declare your converter in a resource section.

<Converters:NullToVisibilityConverter x:Key="NullToVisibilityConverter" />

Where Converters is the place you have placed the converter class. An example is:

xmlns:Converters="clr-namespace:MyProject.Resources.Converters"

The very nice thing about this approach is no repetition of code in your code behind.

Community
  • 1
  • 1
Sivakumar
  • 478
  • 2
  • 13