在WPF中使用DataGrid,我试图通过INotifyDataErrorInfo使用错误验证时获得正确的行为.
我有一个实现该接口的类的ObservableCollection,一个绑定到DataGrid的集合.出现错误时,单元格将显示红色边框,行将显示红色!在前.全部默认,都很好.当还在编辑时,当错误消失时,红色边框和红色!都会消失.到现在为止还挺好!
但是,当我离开行(通过键盘输入/ Tab或鼠标),然后返回它然后删除错误,红色单元格边框消失,但红色!停留.
我知道之前已经提出过这个问题,例如:WPF DataGrid验证错误未清除.但是,除了完全隐藏行验证错误之外,那里的解决方案无法解决此问题.(其中,结合第二个答案,这里也很好......)
或者是我的问题而不是用户能够离开单元格的编辑模式,即使有验证错误?最好,我想限制这一点,并在进一步编辑之前先强制解决错误,但我不知道如何在没有大量代码的情况下强制执行此操作...
这是XML(RowValidationErrorTemplate来自这里:链接):
<UserControl x:Class="CustomDG"
...etc...
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
d:DataContext="{d:DesignInstance Type=viewmodels:TestViewModel}">
<Grid>
<DataGrid
ItemsSource="{Binding Path=testCollection}" AutoGenerateColumns="False"
RowHeight="18" CanUserResizeRows="False" RowHeaderWidth="18" >
<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.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Path=Name,
ValidatesOnNotifyDataErrors=True, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" >
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</UserControl>
Run Code Online (Sandbox Code Playgroud) 对于我正在处理的项目,我需要每秒精确地执行一些逻辑(几乎)10 次。我知道非实时操作系统的局限性,偶尔说 10-20% 的余量是可以的;也就是说,周期之间偶尔延迟最多 120 毫秒是可以的。但是,重要的是我可以绝对保证周期性的逻辑执行,并且不会发生超出上述余量的延迟。这在 C# 中似乎很难实现。
我的情况如下:应用程序启动一段时间后,触发了一个事件,将启动逻辑执行周期。在该循环运行时,该程序还处理其他任务,例如通信、日志记录等。我需要能够在 Windows 上使用 .NET 和在 Linux 上使用 Mono 运行该程序。这不包括导入 winmm.dll 作为使用其高精度计时功能的可能性。
到目前为止我尝试过的:
迄今为止最好的选择似乎是使用 System.Timers.Timer 类。为了更正提到的 109 毫秒,我将时间间隔设置为 92 毫秒(这看起来很糟糕......!)。然后,在事件处理程序中,我使用秒表计算实际经过的时间,然后根据该计算执行我的系统逻辑。
在代码中:
var timer = new System.Timers.Timer(92);
timer.Elapsed += TimerElapsed;
timer.AutoReset = true;
timer.Start();
while (true){}
Run Code Online (Sandbox Code Playgroud)
和处理程序:
private void TimerElapsed(object sender, ElapsedEventArgs e)
{
var elapsed = _watch.ElapsedMilliseconds;
_watch.Restart();
DoWork(elapsed);
}
Run Code Online (Sandbox Code Playgroud)
然而,即使使用这种方法,偶尔也会发生事件仅在超过 200 …