我正在创建一个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;
}
}
有缺失的部分吗?
答案 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>