我想我已经读过所有相关文章,但没有帮助..
我尝试按错误状态启用/禁用datagrid
的保存按钮 - 但没有成功。
这是我的代码:
承包商:
AddHandler(Validation.ErrorEvent, new RoutedEventHandler(OnErrorEvent));
XAML:
<Page
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:col="clr-namespace:System.Collections;assembly=mscorlib"
xmlns:local="clr-namespace:Metsuka_APP" x:Class="Metsuka_APP.MichlolimManagment"
mc:Ignorable="d"
d:DesignHeight="500" d:DesignWidth="500"
Title="MichlolimManagment"
x:Name="Michlolim_Managment" Validation.Error="Michlolim_Managment_Error">
<Page.Resources>
<DataGrid x:Name="AGAFIMDataGrid" VerticalAlignment="Center" RowEditEnding="rowEditEnding" Margin="10" FlowDirection="RightToLeft" Height="340"
AutoGenerateColumns="False" EnableRowVirtualization="True"
ItemsSource="{Binding Source={StaticResource aGAFIMViewSource}}" Grid.Row="1"
RowDetailsVisibilityMode="VisibleWhenSelected"
ScrollViewer.CanContentScroll="True"
ScrollViewer.VerticalScrollBarVisibility="Auto"
HorizontalGridLinesBrush="Silver"
VerticalGridLinesBrush="Silver">
<DataGrid.Resources>
<Style x:Key="errorStyle" TargetType="{x:Type TextBox}">
<Setter Property="Padding" Value="-2"/>
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="Background" Value="Red"/>
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self},
Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn x:Name="agaf_nameColumn" Header="name" Width="*">
<DataGridTextColumn.Binding>
<Binding Path="agaf_name" NotifyOnValidationError="True" >
<Binding.ValidationRules>
<local:MichlolimValidationRule ValidationStep="UpdatedValue"/>
</Binding.ValidationRules>
</Binding>
</DataGridTextColumn.Binding>
</DataGridTextColumn>
</DataGrid.Columns>
<DataGrid.RowValidationErrorTemplate>
<ControlTemplate>
<Grid Margin="0,-2,0,-2"
ToolTip="{Binding RelativeSource={RelativeSource
FindAncestor, AncestorType={x:Type DataGridRow}},
Path=(Validation.Errors)[0].ErrorContent}">
<Ellipse StrokeThickness="0" Fill="Red"
Width="{TemplateBinding FontSize}"
Height="{TemplateBinding FontSize}" />
<TextBlock Text="!" FontSize="{TemplateBinding FontSize}"
FontWeight="Bold" Foreground="White"
HorizontalAlignment="Center" />
</Grid>
</ControlTemplate>
</DataGrid.RowValidationErrorTemplate>
</DataGrid>
代码背后的代码:
private int errorCount;
private void OnErrorEvent(object sender, RoutedEventArgs e)
{
var validationEventArgs = e as ValidationErrorEventArgs;
if (validationEventArgs == null)
throw new Exception("Unexpected event args");
switch (validationEventArgs.Action)
{
case ValidationErrorEventAction.Added:
{
errorCount++; break;
}
case ValidationErrorEventAction.Removed:
{
errorCount--; break;
}
default:
{
throw new Exception("Unknown action");
}
}
btnSavePop.IsEnabled = errorCount == 0;
}
但是"OnErrorEvent"
永远不会发生任何想法?
答案 0 :(得分:3)
尝试创建如下所示的类:
public class AgafDescriptor : INotifyPropertyChanged, IDataErrorInfo
{
private string _name;
public string Name
{
get
{
return _name;
}
set
{
if (_name != value)
{
_name = value;
RaisePropertyChanged(x => x.Name);
}
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged<T>(Expression<Func<AgafDescriptor, T>> propertyExpression)
{
PropertyChangedEventHandler localPropertyChanged = this.PropertyChanged as PropertyChangedEventHandler;
if ((localPropertyChanged != null) && (propertyExpression != null))
{
MemberExpression body = propertyExpression.Body as MemberExpression;
if (body != null)
{
localPropertyChanged(this, new PropertyChangedEventArgs(body.Member.Name));
}
}
}
#endregion
#region IDataErrorInfo Members
// Does nothing in WPF.
public string Error
{
get { return null; }
}
public string this[string columnName]
{
get
{
string returnVal = null;
if (string.Equals("Name", columnName, StringComparison.Ordinal))
{
if (string.IsNullOrWhiteSpace(Name))
{
returnVal = "A name must be supplied.";
}
}
return returnVal;
}
}
#endregion
}
只要Name属性发生更改,这将提供错误。请注意,如果您希望在不修改属性的情况下触发新的验证检查,则只需调用:
RaisePropertyChanged(x => x.Name);
然后,您需要将绑定更改为:
<DataGridTextColumn x:Name="agaf_nameColumn" Header="name" Width="*" Binding="{Binding Name, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay, NotifyOnValidationError=True}"/>
请注意,您必须从数据库加载数据,并为要在DataGrid中显示的每个项目创建描述符。
您没有看到事件被解雇的原因:
您没有提出属性更改事件(INotifyPropertyChanged或通过DependencyProperty),因此UI将不会接收更新,并且不会触发事件,因为它尚未收到更新然后执行验证。通过直接绑定到您的数据库,您不会提出属性更改事件。您可以看到我在答案中建议的Name属性确实引发了属性更改事件
答案 1 :(得分:2)
您需要在绑定上设置NotifyOnValidationError="True"
- 否则,该事件不会被提升。我建议使用mysqli_error($conn);
或IDataErrorInfo
接口代替MVVM错误处理方法。
答案 2 :(得分:2)
属性
Validation.Error="Michlolim_Managment_Error"
在您的XAML中,已经在窗口级别为错误事件设置了一个处理程序,但是,在片段后面的代码中没有定义该方法。您的AddHandler调用看起来没问题,但是,根据它在构造函数中的位置,它可能会被XAML事件处理程序定义覆盖。
可能不相关,但您可能想要更改
(Validation.Errors)[0].ErrorContent
到
(Validation.Errors)/ErrorContent
在您的ToolTip绑定中,因为如果没有错误,前者会导致绑定错误。不幸的是,它仍然包含在文档样本中......
答案 3 :(得分:2)
从我的代码示例中,我认为您缺少在DataGrid中的DataGridTextColumn上指定UpdateSourceTrigger =“PropertyChanged”或UpdateSourceTrigger =“LostFocus”,而不是使用DataGrids绑定的默认行为。
假设我的假设是正确的,请参见底部。
如果我改变了你的代码会导致OnErrorEvent触发:
<DataGridTextColumn.Binding>
<Binding Path="agaf_name" NotifyOnValidationError="True" >
...
包括PropertyChanged或LostFocus的UpdateSourceTrigger,如下所示:
<DataGridTextColumn.Binding>
<Binding Path="agaf_name" NotifyOnValidationError="True" UpdateSourceTrigger="PropertyChanged" >
....
假设 - 对于你的ValidationRule来测试我使它总是返回false(见下文)。对于测试项目源,我绑定到'agaf_name'属性中的字符串值。
public class MichlolimValidationRule : ValidationRule
{
public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
{
return new ValidationResult(false, "bad");
}
}