我试图在我的应用程序中实现验证,并作为示例/教程偶然发现了这一点
https://gist.github.com/holymoo/11243164
实现此功能后,我的xaml中包含以下元素。它可以工作,但是错误消息重叠,所以我寻找了一个解决方案,为什么它会重叠并且显然AdornedElementPlaceholder不会重新呈现整个UI。然后,我查看了样式触发器,并在此处找到了一些关于stackoverflow的示例,但是对我而言,运气不好的话就没有运气了。
<TextBox Text="{Binding GalaxyName, Mode=TwoWay, ValidatesOnDataErrors=True, ValidatesOnNotifyDataErrors=True, ValidatesOnExceptions=True}"
Grid.Column="1" x:Name="GalaxyName" Margin="0,0,10,0">
<Validation.ErrorTemplate>
<ControlTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="20"></RowDefinition>
<RowDefinition Height="auto"></RowDefinition>
</Grid.RowDefinitions>
<Border Grid.Row="1" BorderBrush="Red" BorderThickness="1">
<AdornedElementPlaceholder x:Name="Adorner"/>
</Border>
<TextBlock Grid.Row="0" Foreground="Red" Text="{Binding [0].ErrorContent}"></TextBlock>
</Grid>
</ControlTemplate>
</Validation.ErrorTemplate>
<TextBox.Style>
<Style TargetType="TextBox">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<!-- increase the top margin of the TextBox in order for the error content not to overlap the control above -->
<Setter Property="Margin" Value="0 20 0 0" />
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
Validator
public class GalaxyValidator : AbstractValidator<NewGalaxyViewModel>
{
public GalaxyValidator()
{
RuleFor(user => user.GalaxyName)
.NotEmpty()
.WithMessage("Please Specify a Name.");
}
}
Viewmodel
public class NewGalaxyViewModel : ViewModelBase, INotifyPropertyChanged, IDataErrorInfo
{
private readonly GalaxyValidator _galaxyValidator;
public Galaxy Galaxy { get; set; } = new Galaxy();
public bool DefaultEconomy { get; set; } = false;
public bool DefaultJobs { get; set; } = false;
private RelayCommand _saveCommand = null;
public RelayCommand SaveCommand
{
get { return _saveCommand; }
set { _saveCommand = value; }
}
/** wrapping each property for validation possibilities **/
public long Seed { get { return Galaxy.Seed; } set { Galaxy.Seed = value; } }
public String GalaxyName { get { return Galaxy.GalaxyName; } set { Galaxy.GalaxyName = value; RaisePropertyChanged("GalaxyName"); } }
public String GalaxyPrefix { get { return Galaxy.GalaxyPrefix; } set { Galaxy.GalaxyPrefix = value; } }
public GalaxyOptions GalaxyOptions { get { return Galaxy.GalaxyOptions; } set { Galaxy.GalaxyOptions = value; } }
public String Description { get { return Galaxy.Description; } set { Galaxy.Description = value; } }
public String Author { get { return Galaxy.Author; } set { Galaxy.Author = value; } }
public String Version { get { return Galaxy.Version; } set { Galaxy.Version = value; } }
public String Date { get { return Galaxy.Date; } set { Galaxy.Date = value; } }
public String Save { get { return Galaxy.Save; } set { Galaxy.Save = value; } }
public int MinRandomBelts { get { return Galaxy.MinRandomBelts; } set { Galaxy.MinRandomBelts = value; } }
public int MaxRandomBelts { get { return Galaxy.MaxRandomBelts; } set { Galaxy.MaxRandomBelts = value; } }
public NewGalaxyViewModel() {
this._saveCommand = new RelayCommand(() => OnSaveClicked());
_galaxyValidator = new GalaxyValidator();
}
private void OnSaveClicked()
{
if (DefaultJobs)
{
string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), @"DefaultJson\DefaultJobs.json");
ObservableCollection<Job> jobs = JsonConvert.DeserializeObject<ObservableCollection<Job>>(File.ReadAllText(path));
Galaxy.Jobs = jobs;
}
if (DefaultEconomy)
{
string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), @"DefaultJson\DefaultProducts.json");
ObservableCollection<Product> products = JsonConvert.DeserializeObject<ObservableCollection<Product>>(File.ReadAllText(path));
Galaxy.Products = products;
}
MainData.CreateMapGalaxy(Galaxy, 20, 20, 75);
MainViewModel vm = (App.Current.Resources["Locator"] as ViewModelLocator).Main;
vm.Galaxy = Galaxy;
vm.MainContainer = new MapEditorViewModel(Galaxy);
}
public string this[string columnName]
{
get
{
if(Galaxy != null)
{
var firstOrDefault = _galaxyValidator.Validate(this).Errors.FirstOrDefault(lol => lol.PropertyName == columnName);
if (firstOrDefault != null)
return _galaxyValidator != null ? firstOrDefault.ErrorMessage : "";
}
return "";
}
}
public string Error
{
get
{
if (_galaxyValidator != null)
{
var results = _galaxyValidator.Validate(this);
if (results != null && results.Errors.Any())
{
var errors = string.Join(Environment.NewLine, results.Errors.Select(x => x.ErrorMessage).ToArray());
return errors;
}
}
return string.Empty;
}
}
}
最终结果
我使用这种技术来检查触发器是否正常工作