WPF DataGrid 单元格以红色显示? (菜鸟)
首先我要说的是,我对 WPF 完全陌生。但是,我确实有 20 年的开发经验和大约 5 年的 C# webform 经验。
我正在尝试诊断使用 DataGrid 控件的 WPF 应用程序。
我将尝试描述此应用程序中发生的场景。
以下是产生“错误”的步骤。我试图弄清楚发生了什么:
用户向 DataGrid 表添加一行。 用户将第一列(数量)更改为 1。 用户通过选项卡跨列。 一旦光标经过“Discount Pct”栏并进入下一栏。 此时,“Discount Pct”单元格变为红色。 在“折扣百分比”列被“修复”之前,不能编辑其他单元格。 有趣的是,您可以清除单元格并输入相同的数据,红色就会消失。
我想这可能是因为该字段是一个“百分比”字段(当您输入 0.10 时,当您离开单元格时它会变成“10%”),但另一个(纯文本/varchar)列也发生同样的情况。
我注意到的其他奇怪的事情:
如果用户没有在“数量”单元格中输入任何内容,而只是直接按制表键浏览所有列,直到最后,没有任何单元格会变成红色。
如果用户在折扣百分比单元格上单击(而不是选项卡)(无论是否输入数量),然后离开该单元格(通过单击或选项卡),该单元格不会变成红色。
你知道这里发生了什么吗?我认为存在某种类型的单元验证失败,但为什么只在这些特定情况下?
你会如何诊断这个?我可以以某种方式显示验证错误(我确信一定有一个可以绑定的处理程序),也许这会告诉我一些事情。
想法?有想法吗?
为每个请求添加代码:
<DataGrid x:Name="myDataGrid"
ItemsSource="{Binding}"
CanUserAddRows="False"
CanUserDeleteRows="True"
CanUserResizeRows="False"
SelectionUnit="CellOrRowHeader"
ColumnHeaderStyle="{StaticResource lclDataGridColumnHeaders}"
RowHeaderStyle="{StaticResource lclDataGridRowHeaders}"
CellStyle="{StaticResource lclDataGridCellStyle}"
HorizontalGridLinesBrush="LightBlue"
VerticalGridLinesBrush="LightBlue"
AutoGeneratingColumn="DataGrid_AutoGeneratingColumn"
Loaded="DataGrid_Loaded"
LoadingRow="DataGrid_LoadingRow"
CurrentCellChanged="DataGrid_CurrentCellChanged"
CellEditEnding="DataGrid_CellEditEnding">
</DataGrid>
我弄清楚了如何将样式应用到“EditCell”并使用了以下内容(来自另一个站点):
<Style x:Key="lclDataGridCellEditStyle" TargetType="{x:Type TextBox}">
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Padding" Value="0"/>
<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>
然后,我将其分配给数据网格上的 EditingElementStyle (在代码后面) )。
生成的验证错误(证实了我的怀疑)是:“无法转换值‘10%’”。
这是有道理的,因为它希望用户输入“.10”或类似的东西(浮点/双精度/十进制/等)...而不使用“%”(将条目视为字符/文本)。
问题是,该行被“导入”(从另一个表复制)到 DataGrid 中,因此该字段已填充。那么,如何让 DataGrid 只接受“编辑值”的“显示值”(在这里抛出术语并猜测)?
而且,为什么只有当您更改数量单元格然后使用 Tab 键浏览它时,才会出现此验证错误?
稍后会详细介绍其他领域...一旦我“解决”这个问题,我怀疑解决方案将是类似的...
我可以提供更多代码,但有很多。我试图只提供必要的东西。如果我可以发布其他代码(例如 AutoGenerateColumn,这是非常基本的),请告诉我!
新信息...我猜测数量更改后出现红色框的原因是因为这会触发行更改,从而进行验证。而且,为了解决我上面描述的百分比场景,看起来我需要实现一个“转换器”,如下所述:http://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter.aspx
另一个更新......
这工作了。我将转换器添加到百分比字段,现在一切都很好。
给我带来问题的另一个字段是允许空值的“整数”列。导入记录时,该列为空,但显然 DataGridTextColumn 希望整数不为空。是否有一个属性可以设置为允许空值?或者,我是否只需要做另一个转换器来在..um... null(字符串)和int之间进行转换?哈哈谢恩
I will start by saying that I am completely new to WPF. But, I do have 20 years Development experience and about 5 years of C# webform experience.
I am trying to diagnose a WPF application that uses a DataGrid control.
I am going to try to describe a scenario that is happening in this applicaiton..
Here are the steps that produce the "error". I am trying to figure out what is going on:
The user adds a row to the DataGrid table.
The user changes the first column (Qty) to 1.
The user tabs across the columns.
Once the cursor passes the "Discount Pct" column and enters the next column.
At this momemt, the "Discount Pct" cell becomes outlined in Red.
No other cells can be edited until the "Discount Pct" column has been "fixed".
The funny thing is, you can clear the cell and type the same data and the red goes away.
I thought maybe this was because the field is a "percentage" field (when you type .10, it becomes "10 %" when you leave the cell), but the same thing is happening with another (plain text/varchar) column.
Other weird things I have noticed:
If the user doesn't enter anything in the Qty cell, but just tabs straight through all the columns, to the end, none of the cells turn red.
If the user clicks (instead of tab) on the Discount Pct cell (whether a Qty is entered or NOT), then leaves that cell (with a click or tab), the cell DOESN'T turn red.
Any ideas what is happening here? I suppose there is some type of Cell Validation failing, but why only under these specific circumstances?
How would you diagnose this? Can I display the validation error somehow (I am sure there must be a handler I can tie in to), maybe that will tell me something.
Thoughts? Ideas?
Adding code per requests:
<DataGrid x:Name="myDataGrid"
ItemsSource="{Binding}"
CanUserAddRows="False"
CanUserDeleteRows="True"
CanUserResizeRows="False"
SelectionUnit="CellOrRowHeader"
ColumnHeaderStyle="{StaticResource lclDataGridColumnHeaders}"
RowHeaderStyle="{StaticResource lclDataGridRowHeaders}"
CellStyle="{StaticResource lclDataGridCellStyle}"
HorizontalGridLinesBrush="LightBlue"
VerticalGridLinesBrush="LightBlue"
AutoGeneratingColumn="DataGrid_AutoGeneratingColumn"
Loaded="DataGrid_Loaded"
LoadingRow="DataGrid_LoadingRow"
CurrentCellChanged="DataGrid_CurrentCellChanged"
CellEditEnding="DataGrid_CellEditEnding">
</DataGrid>
I figured out how to apply a Style to the "EditCell" and ued the following (from another site):
<Style x:Key="lclDataGridCellEditStyle" TargetType="{x:Type TextBox}">
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Padding" Value="0"/>
<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>
Then, I assigned that to the EditingElementStyle on the datagrid (in code behind).
The Validation error generated (confirms my suspicions) is: "Value '10 %' could not be converted".
This makes sense, because it is wanting the user to enter ".10" or somethinig similar (a float/double/decimal/etc)...without the "%" (treating the entry as char/text).
The issue is, this row is "imported" (copied from another table) into the DataGrid and therefore, the field is already populated. So, how can I get the DataGrid to just accept the "display value" (throwing around terms and guessing here) for the "Edit Value"?
And, why only when you Change the Qty Cell and then tab through it, does this Validation error occur?
More on the other field later...once I "solve" this one, I suspect the solution will be similar...
I can give more code, but there is alot. I am trying to just give what is necessary. If I can post an of the other code (such as AutoGeneratingColumn, which is very basic), let me know!
New information... I am guessing the reason the red box shows up after the Qty is changed, is because that triggers a row change, which does a validation. And, to fix the percentage scenario I described above, it looks like I will need to implement a "converter" as described here: http://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter.aspx
Another Update....
This worked. I added the Converter to the Percentage field and now all is good for that one.
The other field that is giving me problems is an "integer" column that allows nulls. When the record is imported, that column is null, but evidently the DataGridTextColumn wants ints to NOT be null. Is there a property I can set to allow nulls? Or, do I simply need to do another converter to convert between..um... null (string) and int?? lol
Shayne
您也许可以有一个 int 类型的列?这将允许空值。
You might be able to have a column that is of type int? which would allow for nulls.