【问题标题】:Name on combobox in WPFWPF中组合框上的名称
【发布时间】:2012-08-10 08:45:54
【问题描述】:

当我在 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;

【问题讨论】:

  • 为什么您希望组合框的名称(=“您的选择”)在用户单击时消失?如果用户点击组合框(使名称消失),然后直接点击它的外部怎么办?
  • 您是否尝试在您的组合框上覆盖标签控件?
  • 不,我不想让它消失,我只是不想让它消失两次!正如我现在的代码一样,我在“按钮”和下拉项中都获得了“您的选择”。

标签: c# wpf


【解决方案1】:

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

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

【讨论】:

    【解决方案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
    }
    

    希望这会有所帮助!

    【讨论】:

    • 仅供参考:当您使用四个空格缩进代码时,您不需要添加反引号。只有内联代码块才需要反引号。
    • 我明白了。感谢那!这是我的第一个答案,所以我不完全确定它是如何工作的。
    【解决方案3】:

    试试这个,我刚测试过

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

    【讨论】:

    • 好的,但是我把名字“你的选择”然后呢?
    • 我也会从 strChangeRoute 中删除“您的选择”
    • 嗯,没关系,但我得到一个空的白线作为第一项!?有办法消除吗?
    • 您得到空行,因为“您的选择..”元素仍然存在,它刚刚被隐藏(请注意,您仍然可以使用键盘箭头选择它)。这是此解决方案不是最佳解决方案的众多原因之一。
    • 实际上我已经更新了我的答案,这是可能的,而且代码行数更少
    【解决方案4】:

    我会在 ComboBox 上寻找一个 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;
        }
    

    或者,更好的解决方案:纯 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>
    

    在这种情况下,不要忘记从代码隐藏中设置内容控件的数据上下文:

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

    【讨论】:

    • 这也可以使用触发器来完成,这是最好的使用方式(在我看来)
    • 谢谢 Piotr Ptak,我在答案中添加了一个使用触发器的解决方案。
    【解决方案5】:

    你可以参考这个, 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" />
    

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

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

    这种方法的好处是在你的代码中没有重复代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-14
      • 2023-03-05
      • 1970-01-01
      相关资源
      最近更新 更多