2012-08-10 58 views
1

当我在WPF中创建组合框时,我希望它有一个名称就像“你的选择”,就像它是一个普通的按钮,当我点击它时,我只想要项目下拉菜单,而不是组合框上的名称。我希望你明白我的问题?有没有办法解决这个问题?在WPF中的组合框名称

在XAML我用这个组合框:

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

我在C#代码添加项目是这样的:

string[] strChangeRoute = new string[] { "Your choice", "10 deg", "20 deg", "30 deg" }; 
foreach (string s in strChangeRoute) 
    cmbChangeRoute.Items.Add(s); 
cmbChangeRoute.SelectedIndex = 0; 
+0

为什么你想让组合框的名称(=“你的选择”)在用户点击时消失?如果用户点击comboxbox(使名称消失),然后直接单击它在外面呢? – franssu 2012-08-10 08:55:50

+0

你是否试图在你的组合框上叠加一个标签控件? – NoviceProgrammer 2012-08-10 08:58:35

+0

不,我不想让它消失,我只是不想要它两次!正如我现在的代码一样,我在“按钮”和下拉菜单中都可以看到“您的选择”。 – 2012-08-10 09:01:41

回答

2

我会去一个TextBlock在组合框谁的知名度将被绑定到ComboBox的selectedItem(通过转换器)。

<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,更好的解决方案:纯XAML中,使用触发器:

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

在这种情况下,不要忘记从代码隐藏设置的内容控制的的DataContext:

myContentControl.DataContext = Enum.GetValues(typeof([YOUR ENUM])); 
+0

这也可以使用触发器,这是最好的使用方式(在我看来) – 2012-08-10 09:42:21

+0

谢谢Piotr Ptak,我添加了一个解决方案,使用触发器来回答我的问题。 – franssu 2012-08-10 11:54:16

2

试试这个,我刚刚测试过

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

好的,但是我把名字叫做“你的选择”吗? – 2012-08-10 09:43:12

+0

我会从strChangeRoute中删除“您的选择” – 2012-08-10 09:45:46

+0

嗯,没关系,但是我得到一个空的白线作为第一项!?有没有办法消除这种情况? – 2012-08-10 09:52:29

2

您是否尝试过使用绑定?

在XAML中你碰到这样的

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

然后,在你的构造(代码隐藏)只需添加行

this.DataContext = this; 

让你的绑定实际上看在代码 - 在后面查找依赖属性ChosenValue。这样,每当组合框中的值发生变化时,您的道具的值将更新以保存当前选择的项目。

达到你想要什么,只是设置道具的价值,以“您的选择”在构造函数中

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

类似的,只是它的值设置为相同的字符串在其他地方你想要的。当保存或什么,只是检查

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

希望这有助于!

+0

仅供参考:当您用四个空格缩进代码时,不需要添加反引号。反引号仅用于内联代码块。 – quetzalcoatl 2012-08-10 09:52:00

+0

我明白了。感谢那!这是我的第一个答案,所以我不完全确定它是如何工作的。 – Dorian 2012-08-10 10:59:22

2

你想要做的事实不是配置ComboBox,而是在它上面添加一个装饰器/装饰器,当Combo关闭时会显示一个文本,并且在组合关闭时会自动隐藏。它有时被称为“水印”。

我不会进一步解释它,因为它毫无意义。这里有一篇不错的文章:http://pwlodek.blogspot.com/2009/11/watermark-effect-for-wpfs-textbox.html还有所有为组合框加水印所需的代码片段。

0

你可以参照这一条, How to display default text "--Select Team --" in combo box on pageload in WPF?

我建议从这个论坛下面的解决方案,

您可以使用的IValueConverter做到这一点无需任何代码后面。

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

在这里你有转换器类,你可以重新使用。

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 
} 

最后,您需要在资源部分声明您的转换器。

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

其中转换器是放置转换器类的地方。一个例子是:

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

这种方法非常好的一点是没有重复的代码在你的代码背后。