【问题标题】:Cancel Edit Mode in WPF DataGrid even when validation fires即使触发验证,也取消 WPF DataGrid 中的编辑模式
【发布时间】:2013-12-25 03:57:07
【问题描述】:

我是 wpf 的新手,我需要使用 WPF DataGrid,它的 ItemSource 设置为 Model 类型的 ObservableCollection,其中 Model 实现了 IDataErrorInfo 类。 我面临的问题是,如果模型返回任何属性的验证字符串,则用户无法退出单元格的编辑模式,我尝试回滚,甚至尝试取消编辑,但我无法退出编辑模式.我在 msdn 上进行了搜索,发现它是 DataGrid 的属性之一,但由于某些应用程序要求,我需要这样做。

我的模型课:

public class Model: IDataErrorInfo
{
    public int PropertyName{ get; set; }

    // other properties & methods removed for clarity

    public string this[columnName]
    {
        get
        {
            if (PropertyName< 0)
                return "Error Message";
            else
                return string.Empty;
        }
    }
}

现在如果 'PropertyName' 小于 0,用户将无法退出特定单元格的编辑模式。

This link on msdn 在“备注”中说

DataGrid 在验证之前不会退出单元格编辑模式 错误已解决。

即使验证返回错误消息,是否有任何解决方法可以退出单元格编辑模式?我对代码架构无能为力,因为我被 DataGrid 和“模型”类困住了。任何帮助将不胜感激,非常感谢。

【问题讨论】:

  • 如果您将单元格更改回之前的有效状态,用户应该如何收到他做错事的通知。他可能会不断重复在单元格中设置 -1,但它总是会改回 0。(如果 0 是编辑前的当前值)。你真的想要这个吗?
  • 基本上它只是我应用程序需求的一小部分。有一个错误列表,用户选择一个错误,焦点自动转到该元素,现在如果用户在网格中选择其他错误,焦点不会改变,因为旧错误没有修复,但我希望焦点更改为新选择的错误,并且网格不允许更改编辑元素。 (我正在使用 WPF 工具包网格)。如果旧的错误得到修复,我可以改变焦点。
  • 但是您永远不会将任何项目添加到该错误列表中,因为您需要先修复单元格中的错误,然后才能离开单元格大声笑。那么又有什么意义呢。告诉我们更多信息你为什么这样做。也许我们会为您找到更好的建议。你所说的清单永远不会被填满。
  • 我完全明白你的意思.. 但是我的应用程序要求.. 我无法正确解释它.. 我通过在 this[columnName] 中添加错误来填充列表(在我的模型中继承自IDataErrorInfo),所以列表被填满了。通过验证约束,我基本上是指“属性应该在 10 到 20 之间” 之类的东西。现在假设用户添加了一个新行,验证发生在 4 个属性上,因此列表将被填充(已填充,如果需要,我可以提供代码)。
  • 我想要的是用户能够在错误之间导航,而不必修复它们。 (该错误列表也有其他错误,就像整个应用程序的全局错误列表)。示例代码有帮助吗?

标签: wpf wpfdatagrid wpftoolkit idataerrorinfo


【解决方案1】:

使用 IdataErrorInfo 验证 WPF DataGrid, 在解决验证错误之前,DataGrid 不会退出单元格编辑模式。

这是真的,但可以通过变通方法克服 - 使用 DataGridTemplateColumn.CellEditingTemplate 和 DataGridTemplateColumn.CellTemplate 中的 TextBox

为数据网格定义一个数据模板

    <DataGrid.Resources> 
    .... 
    <DataTemplate x:Key="EditingValueTemplate">
        <TextBox Text="{Binding bindingProp, ValidatesOnDataErrors=True}"
                                  FocusManager.FocusedElement="{Binding RelativeSource=  {RelativeSource Self}}"/>
    </DataTemplate>
</DataGrid.Resources>

将此数据模板分配给数据网格的 CellTemplate 和 CellEditingTemplate

    <DataGrid.Columns>
<DataGridTemplateColumn Header="Value" CellTemplate="{StaticResource EditingValueTemplate}" 
                                        CellEditingTemplate="{StaticResource EditingValueTemplate}" />
</DataGrid.Columns>

如果您想指定工具提示以在两种情况下显示错误,即单元格编辑模式和鼠标悬停单元格。 你需要一种风格

    <Style x:Key="DatagridCellToolTip" TargetType="{x:Type DataGridCell}">
        <Style.Triggers>
            <Trigger Property="Validation.HasError" Value="true">
                <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
            </Trigger>
</Style.Triggers>
</Style>

并在上述数据网格中包含此样式,即

<DataGrid.Columns>
    <DataGridTemplateColumn Header="Value" CellTemplate="{StaticResource EditingValueTemplate}" 
                                            CellEditingTemplate="{StaticResource EditingValueTemplate}" 
                                            CellStyle="{StaticResource DatagridCellToolTip}"/>
</DataGrid.Columns>

【讨论】:

  • 是的,我试过了,但是有没有使用 DataGridTextColumn 的解决方法。 (因为至少你愿意回答,所以投票赞成)
  • 据我所知,如果存在验证错误并且单元格处于编辑模式,则 DataGrid 会将其余单元格锁定为不可编辑,或者说单元格的行为符合基于 TextBlock 而不是基于 CellTemplate 的定义文本框。 DataGridTextColumn 使用默认的 cellTemplate 定义,因此我们不得不使用 DataGridTemplateColumn 并强制它使用 TextBox。不过我的知识有限。
  • 我对 DataGridTextColumn 的体验是,即使出现验证错误,Escape 键也会取消编辑。我试图在 DataGridTemplateColumn 中使用 CellEditingTemplate 中的 DatePicker 获得相同的行为。 (stackoverflow.com/q/37029641/107037)
【解决方案2】:

我只是偶然发现了这一点。

当您将每个 DataGridTextColumn 替换为 TemplateColumn 并绑定到 TextBox 时,即使错误未修复,您也可以在每个 TextBox 之间跳转并编辑多行。

<DataGridTemplateColumn Header="Sample" Width="1*">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBox VerticalAlignment="Stretch" HorizontalAlignment="Stretch" >
                <TextBox.Text>
                    <Binding Path="SampleB" UpdateSourceTrigger="PropertyChanged">
                        <Binding.ValidationRules>
                            <vm:CellDataInfoValidationRule ValidationStep="UpdatedValue"/>
                        </Binding.ValidationRules>
                    </Binding>
                </TextBox.Text>
            </TextBox>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-19
    • 2013-02-08
    • 1970-01-01
    • 2014-08-08
    相关资源
    最近更新 更多