这可能是预期的功能,但对我来说肯定是个错误。
我正在使用开箱即用的WPF DataGrid,绑定到ObservableCollection并尝试使用一些验证规则以提供良好的用户反馈。毋庸置疑,有更多的问题比我可以计算的多,但我会坚持立即。
以下是问题摘要:
ItemsSource
属性绑定到ObservableCollection<T>
ObservableCollection<T>
执行这些步骤后,GridView会正确识别该项目已从集合中删除,并从网格中删除该行。但是,网格现在处于无效状态,并且无法通过网格上的UI执行进一步的操作!
同样,这似乎是一个很大的错误,因为能够以编程方式从集合中删除项目是一件大事。
有没有人碰到这个?有关如何绕过它的任何建议吗?
值得注意的是,我已经创建了一个单独的解决方案,只是为了解决这个问题,但回答了一些问题:
您的对象是否实现了INotifyPropertyChanged
? 是
这是一个自定义集合吗? 没有普通的ObservableCollection<T>
如何从收藏中删除商品?
//Find any newly added item and remove it
var someObject = SomeObjects
.Where(obj => obj.SomeProperty == SomeValue)
.First();
SomeObjects.Remove(someObject );
您如何绑定验证规则?
<DataGridTextColumn Header="SomeProperty">
<DataGridTextColumn.Binding>
<Binding Path="SomeProperty">
<Binding.ValidationRules>
<val:RequiredValidator ValidationStep="ConvertedProposedValue"
ValidatesOnTargetUpdated="True" />
</Binding.ValidationRules>
</Binding>
</DataGridTextColumn.Binding>
</DataGridTextColumn>
您的验证规则是什么样的?
public class RequiredValidator : ValidationRule
{
public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
{
if (value == null || String.IsNullOrWhiteSpace(value as String))
return new ValidationResult(false, "Field is required!");
return ValidationResult.ValidResult;
}
}
答案 0 :(得分:1)
我遇到了同样的问题,经过漫长的搜索过程后,我找到了解决方案:
您可以创建一个派生自DataGrid的类。在那里,您可以通过反射访问私有财产。如果您现在删除了无效项,则可以调用函数SetGridWritable(),其他值可以再次编辑。
public class MyDataGrid : DataGrid
{
public void SetGridWritable()
{
BindingFlags bindingFlags = BindingFlags.FlattenHierarchy | BindingFlags.NonPublic | BindingFlags.Instance;
PropertyInfo cellErrorInfo = this.GetType().BaseType.GetProperty("HasCellValidationError", bindingFlags);
PropertyInfo rowErrorInfo = this.GetType().BaseType.GetProperty("HasRowValidationError", bindingFlags);
cellErrorInfo.SetValue(this, false, null);
rowErrorInfo.SetValue(this, false, null);
}
}
答案 1 :(得分:1)
我花了几个小时试图找出发生了什么。最后,对项目的简单刷新解决了这个问题。希望这会有所帮助。
YourDataGrid.Items.Refresh();
答案 2 :(得分:0)
如果您有兴趣,我有一个非解决方案:
我们发现整个验证机制充满了不必要的行为。 例如 - 我们希望允许用户输入无效数据,并仅标记错误。
为此,我们创建了一个带有红框的单元格模板,该框架与数据触发器绑定,只要给定属性的错误状态发生变化,就会调用该数据触发器。 datatrigger的实际创建是由依赖项属性完成的,该属性接收ViewModel属性的绑定路径并创建绑定
即:
DataTrigger errorTrigger = CreateTrigger(CreateDirectBinding(property,new HasErrorValueConverter()), CreateErrorSetter(property));
这解决了与验证错误相关的问题。