C#WPF Combobox可编辑仅允许列表中的选项

时间:2017-02-10 14:53:26

标签: c# wpf visual-studio validation combobox

我有一个名字在其中的组合框。我将框设置为可编辑,以便用户可以输入名称。我想要它,以便用户只能输入列表中已有的名称。 当用户单击“保存”时,如果框中的框为空,​​则我希望该框显示红色验证边框。 有没有办法做到这一点?

        <ComboBox IsEditable="True"
                  Grid.Column="2"
                  Grid.Row="1"
                  Margin="5,3,0,0"
                  Text="{Binding Model.Number}"
                  ItemsSource="{Binding DList}"
                  SelectedItem="{Binding Model.Number}"
                  IsEnabled="{Binding EnableComboBox}" 
                  VerticalAlignment="Top">
        </ComboBox>

2 个答案:

答案 0 :(得分:2)

如果我理解正确,您希望用户能够通过键入来选择现有列表项,但不能键入不在列表中的字符串。这可以通过以下方式完成:

<ComboBox IsEditable="False"></ComboBox>

这将允许用户开始输入字符串,但是您丢失了输入的文本框。

另一种方法是允许用户通过设置<ComboBox IsReadOnly="False" IsEditable="True">键入他们想要的任何内容并处理例如LostFocus事件以检查输入是否有效。这是一个例子:

private void ComboBox_LostFocus(object sender, RoutedEventArgs e)
    {
        bool allowed = false;
        foreach (ComboBoxItem it in comboBox.Items)
        {
            if (it.Content.ToString() == comboBox.Text)
            {
                allowed = true;
                break;
            }
        }

        if (!allowed)
        {
            MessageBox.Show("MISS!");
        }

        else
        {
            MessageBox.Show("HIT!");
        }
    }

出于某种原因,我无法快速设置边框颜色,但是你从这里得到了重点。另外,根据您的ComboBoxItem类型,您可能需要将comboBox.Text与某个属性相匹配。

答案 1 :(得分:2)

让我们假设你使用MVVM(它不是你现在正在做的)和那个

ItemsSource="{Binding DList}"

是对模型集合的正确绑定

你需要一个

DisplayMemberPath="Number"

回到你的问题。 首先,让我们为所选文本

编写另一个绑定
Text="{Binding Selected, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors =true, NotifyOnValidationError=true}"

并在组合

中实现验证工具提示
ToolTip="{Binding ElementName=customAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}"

和窗口资源中的样式

<Window.Resources>
    <Style TargetType="{x:Type Label}">
        <Setter Property="Margin" Value="5,0,5,0" />
        <Setter Property="HorizontalAlignment" Value="Right" />
    </Style>
    <Style TargetType="{x:Type ComboBox}">
        <Setter Property="VerticalAlignment" Value="Center" />
        <Setter Property="Margin" Value="0,2,40,2" />
        <Setter Property="Validation.ErrorTemplate">
            <Setter.Value>
                <ControlTemplate>
                    <DockPanel LastChildFill="true">
                        <Border Background="Red" DockPanel.Dock="right" Margin="5,0,0,0" Width="20" Height="20" CornerRadius="10"
                                ToolTip="{Binding ElementName=customAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">
                            <TextBlock Text="!" VerticalAlignment="center" HorizontalAlignment="center" FontWeight="Bold" Foreground="white">
                            </TextBlock>
                        </Border>
                        <AdornedElementPlaceholder Name="customAdorner" VerticalAlignment="Center" >
                            <Border BorderBrush="red" BorderThickness="1" />
                        </AdornedElementPlaceholder>
                    </DockPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>

最后,我们要验证ViewModel属性

我们可以将模型列表投影到其错误检查的数字

    public class VM : IDataErrorInfo
    {
        public string this[string columnName]
        {
            get
            {
                if (columnName.Equals( "Selected"))
                {
                    if (!DList.Select(m => m.Number).Contains(Selected))
                        return "Selected number must be in the combo list";
                }
                return null;
            }
        }

您可以在MVVM中了解有关数据验证的更多信息,例如here

稍后触发验证

假设您希望在单击保存按钮后激活验证

    <Button Content="Save" 
            Command="{Binding SaveCmd}"

您只需要在相应的委托命令

中引发更改的属性
    public class VM : ViewModelBase, IDataErrorInfo
    {
        private bool showValidation;
        private int selected;
        public int Selected
        {
            get { return selected; }
            set
            {
                selected = value;
                showValidation = true;
                OnPropertyChanged("Selected");
            }
        }
        DelegateCommand saveCmd;
        public ICommand SaveCmd
        {
            get
            {
                if (saveCmd == null)
                {
                    saveCmd = new DelegateCommand(_ => RunSaveCmd(), _ => CanSaveCmd());
                }
                return saveCmd;
            }
        }

        private bool CanSaveCmd()
        {
            return true;
        }

        private void RunSaveCmd()
        {
            showValidation = true;
            OnPropertyChanged("Selected");
        }

并在您想要显示之前退出验证。

        public string this[string columnName]
        {
            get
            {
                if (!showValidation)
                {
                    return null;
                }