3D-kreativ
3D-kreativ

Reputation: 9297

Name on combobox in WPF

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;

Upvotes: 1

Views: 9245

Answers (5)

franssu
franssu

Reputation: 2430

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]));

Upvotes: 2

Clinton Ward
Clinton Ward

Reputation: 2511

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

Upvotes: 2

Sivakumar
Sivakumar

Reputation: 478

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.

Upvotes: 0

Ivan Petkov
Ivan Petkov

Reputation: 141

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!

Upvotes: 2

quetzalcoatl
quetzalcoatl

Reputation: 33526

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.

Upvotes: 2

Related Questions