验证不适用于自定义usercontrol组合框

时间:2018-01-09 20:47:23

标签: c# wpf xaml user-controls

我正在创建一个Usercontrol,其中包含一个下拉列表,打开下拉列表时,我想要一个Add按钮。一切正常,但验证不适用于Usercontrol控件。

这是我的xaml代码:

<UserControl x:Class="Splendid.Inventory.Presentation.Controls.CustomComboBox"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:Splendid.Inventory.Presentation.Controls"
             xmlns:conv="clr-namespace:Splendid.Inventory.Presentation.Converters"
             mc:Ignorable="d" x:Name="ucCombo" Validation.ErrorTemplate="{x:Null}"
             d:DesignHeight="30" d:DesignWidth="100">
    <UserControl.Resources>
        <KeyBinding x:Key="addNewBinding" Key="N" Modifiers="Shift" Command="{Binding AddNewCommand}"></KeyBinding>
        <conv:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"></conv:BooleanToVisibilityConverter>
    </UserControl.Resources>

    <Grid x:Name="LayoutRoot">
        <ComboBox x:Name="hdnCombo" MaxDropDownHeight="200" Visibility="Visible" Style="{StaticResource DialogCombobox}"
                         DisplayMemberPath="{Binding DisplayMemberPath, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"
                         SelectedValuePath="{Binding SelectedValuePath, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"
                         SelectedValue="{Binding SelectedValue,UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnValidationError=True}"
                         ItemsSource="{Binding ItemSource, UpdateSourceTrigger=PropertyChanged}"
                         GotFocus="hdnCombo_GotFocus" LostFocus="hdnCombo_LostFocus">
        </ComboBox>

        <Canvas Visibility="{Binding IsDropDownOpen, ElementName=hdnCombo, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource BooleanToVisibilityConverter}}">
            <Grid Canvas.Top="200">
            <Button HorizontalAlignment="Center" VerticalAlignment="Center" x:Name="btnTesst" 
                    MouseEnter="btnTesst_MouseEnter">Add New (Shift + N)</Button>
            </Grid>
        </Canvas>
    </Grid>
</UserControl>

我尝试使用字符串属性绑定和文本框进行usercontrol,我能够收到错误。

这是我的xaml.cs代码:

public partial class CustomComboBox : UserControl, INotifyPropertyChanged, IDataErrorInfo
    {
        public ICommand AddNewCommand { get; set; }
        public CustomComboBox()
        {
            InitializeComponent();
            //this.DataContext = this;
            LayoutRoot.DataContext = this;
            AddNewCommand = new DelegateCommand(OnAddNewCommand);
        }

        private void OnAddNewCommand()
        {
            MessageBox.Show("Add New form");
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public IEnumerable ItemSource
        {
            get { return (IEnumerable)GetValue(ItemSourceProperty); }
            set
            {
                SetValue(ItemSourceProperty, value);
            }
        }

        // Using a DependencyProperty as the backing store for ListItemSource.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ItemSourceProperty =
            DependencyProperty.Register("ItemSource", typeof(IEnumerable), typeof(CustomComboBox));


        public string AddItemControl
        {
            get { return (string)GetValue(AddItemControlProperty); }
            set { SetValue(AddItemControlProperty, value); }
        }

        // Using a DependencyProperty as the backing store for AddItemControl.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty AddItemControlProperty =
            DependencyProperty.Register("AddItemControl", typeof(string), typeof(CustomComboBox), new PropertyMetadata(string.Empty));

        public string DisplayMemberPath
        {
            get { return (string)GetValue(DisplayMemberNameProperty); }
            set { SetValue(DisplayMemberNameProperty, value); }
        }

        // Using a DependencyProperty as the backing store for DisplayMemberPath.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty DisplayMemberNameProperty =
            DependencyProperty.Register("DisplayMemberPath", typeof(string), typeof(CustomComboBox), new PropertyMetadata(string.Empty));


        public string SelectedValuePath
        {
            get { return (string)GetValue(SelectedValueNameProperty); }
            set { SetValue(SelectedValueNameProperty, value); }
        }

        // Using a DependencyProperty as the backing store for SelectedValuePath.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty SelectedValueNameProperty =
            DependencyProperty.Register("SelectedValuePath", typeof(string), typeof(CustomComboBox), new PropertyMetadata(string.Empty));


        public SelectListModel SelectedItem
        {
            get { return (SelectListModel)GetValue(SelectedItemProperty); }
            set
            {
                SetValue(SelectedItemProperty, value);
            }
        }

        // Using a DependencyProperty as the backing store for SelectedItem.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty SelectedItemProperty =
            DependencyProperty.Register("SelectedItem", typeof(SelectListModel), typeof(CustomComboBox));

        public object SelectedValue
        {
            get { return GetValue(SelectedValueProperty); }
            set { SetValue(SelectedValueProperty, value); }
        }

        // Using a DependencyProperty as the backing store for SelectedValue.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty SelectedValueProperty =
            DependencyProperty.Register("SelectedValue", typeof(object), typeof(CustomComboBox));

        public int ItemUnitId
        {
            get { return (int)GetValue(ItemUnitIdProperty); }
            set { SetValue(ItemUnitIdProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ItemName.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ItemUnitIdProperty =
            DependencyProperty.Register("ItemUnitId", typeof(string), typeof(CustomComboBox), new FrameworkPropertyMetadata(string.Empty,
                FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)
);



        public string Error
        {
            get
            {

                return "Item type is required";
                //throw new NotImplementedException();
            }
        }

        public string this[string columnName]
        {
            get
            {

                // use a specific validation or ask for UserControl Validation Error 
                return Validation.GetHasError(this) ? Convert.ToString(Validation.GetErrors(this).FirstOrDefault().ErrorContent) : null;
            }
        }

        private void btnTesst_MouseEnter(object sender, MouseEventArgs e)
        {
            OnAddNewCommand();
        }

        bool isFocused = false;
        private void hdnCombo_GotFocus(object sender, RoutedEventArgs e)
        {
            isFocused = true;
        }

        private void hdnCombo_LostFocus(object sender, RoutedEventArgs e)
        {
            isFocused = false;
        }
    }

有缺失的部分吗?

1 个答案:

答案 0 :(得分:0)

通过向用户控件添加验证模板解决了该问题。以下是对UserControl所做的更改:

<UserControl x:Class="Splendid.Inventory.Presentation.Controls.CustomComboBox"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:Splendid.Inventory.Presentation.Controls"
             xmlns:conv="clr-namespace:Splendid.Inventory.Presentation.Converters"
             mc:Ignorable="d" x:Name="ucCombo"
             Validation.ErrorTemplate="{StaticResource ValidationErrorTemplate}"
             d:DesignHeight="30" d:DesignWidth="100">
    <UserControl.Resources>
        <KeyBinding x:Key="addNewBinding" Key="N" Modifiers="Shift" Command="{Binding AddNewCommand}"></KeyBinding>
        <conv:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"></conv:BooleanToVisibilityConverter>
    </UserControl.Resources>

    <Grid x:Name="LayoutRoot">
        <ComboBox x:Name="hdnCombo" MaxDropDownHeight="200" Visibility="Visible" Style="{StaticResource DialogCombobox}"
                         DisplayMemberPath="{Binding DisplayMemberPath, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"
                         SelectedValuePath="{Binding SelectedValuePath, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"
                         SelectedValue="{Binding SelectedValue,UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnValidationError=True}"
                         ItemsSource="{Binding ItemSource, UpdateSourceTrigger=PropertyChanged}"
                         GotFocus="hdnCombo_GotFocus" LostFocus="hdnCombo_LostFocus">
        </ComboBox>

        <Canvas Visibility="{Binding IsDropDownOpen, ElementName=hdnCombo, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource BooleanToVisibilityConverter}}">
            <Grid Canvas.Top="200">
            <Button HorizontalAlignment="Center" VerticalAlignment="Center" x:Name="btnTesst" 
                    MouseEnter="btnTesst_MouseEnter">Add New (Shift + N)</Button>
            </Grid>
        </Canvas>
    </Grid>
</UserControl>