我在下面编写了一个断言方法Ensure.CurrentlyOnUiThread(),用于检查当前线程是否为UI线程.
Ensure.cs
using System.Diagnostics;
using System.Windows.Forms;
public static class Ensure
{
[Conditional("DEBUG")]
public static void CurrentlyOnUiThread()
{
if (!Application.MessageLoop)
{
throw new ThreadStateException("Assertion failed: not on the UI thread");
}
}
}
Run Code Online (Sandbox Code Playgroud) 从MSDN,似乎Application.DoEvents()在Windows.Forms中可用.什么是WPF中的等价物.
我正在使用此代码段来分析我在数据网格上选择的行.
for (int i = 0; i < dgDetalle.Items.Count; i++)
{
DataGridRow row = (DataGridRow)dgDetalle.ItemContainerGenerator.ContainerFromIndex(i);
FrameworkElement cellContent = dgDetalle.Columns[0].GetCellContent(row);
// ... code ...
}
Run Code Online (Sandbox Code Playgroud)
循环运行平稳,但在处理某些索引时,第二行会抛出一个空异常.MSDN的文档说ItemContainerGenerator.ContainerFromIndex(i)如果'如果项目没有实现'将返回null,但这无助于我猜测如何获得所需的值.
如何扫描所有行?还有其他方法吗?
UPDATE
我正在使用这个片段来阅读这里CheckBox解释的内容.所以除非我改变很多东西,否则我不能使用绑定或根本不使用绑定.我不能.我正在进行代码维护.ItemSource
我有一个带有statusLabel的Windows窗体(C#.NET),我似乎无法在事件处理程序方法的过程中更新.我的代码看起来像这样......
void Process_Completed(object sender, EventArgs e)
{
string t = "Process is finished!";
this.Invoke(new StatusLabelUpdator(updateStatusLabel), new object[] { t });
}
void Process_Started(object sender, EventArgs e)
{
string t = "Process has begun";
this.Invoke(new StatusLabelUpdator(updateStatusLabel), new object[] { t });
}
private delegate void StatusLabelUpdator(string text);
private void updateStatusLabel(string text)
{
StatusLabel1.Text = text;
statusStrip1.Invalidate();
statusStrip1.Refresh();
statusStrip1.Update();
}
Run Code Online (Sandbox Code Playgroud)
当我运行代码时,一旦进程启动,就会触发Process_Started方法,几秒钟后会触发Process_Completed方法.由于某种原因,我不能让状态标签显示"过程已经开始".它只显示"过程完成!".正如您所看到的,我已尝试使包含状态标签但未成功的状态条无效,刷新和更新.我无法在statuslabel本身上调用update/refresh/invalidate,因为这些方法不可用.我究竟做错了什么?
添加信息:
通过单击窗体上的按钮启动"进程",该窗体在单独的类中调用方法,如下所示:
public void DoSomeProcess()
{
TriggerProcessStarted();
System.Threading.Thread.Sleep(2000); // For testing..
TriggerProcessComplete();
}
Run Code Online (Sandbox Code Playgroud)
在TriggerProcessxxxx方法中,我使用此代码触发事件...
var EventListeners = EH.GetInvocationList(); //EH is the …Run Code Online (Sandbox Code Playgroud) 据我所知,调度程序发生在另一个线程中,它负责更新数据绑定,布局等.但是,有没有办法等到调度程序没有更多的项目或至少没有更多的数据绑定?我想确保属性更改已更新其所有组件,并在运行更多代码之前运行依赖属性更改的回调.
编辑:所以我猜这不是必需的,我只是想了解我应该做些什么.我的主要问题是WPF,如果滚动查看器的子项调整大小,滚动查看器会自动更新其范围吗?
但我也很好奇我是否可以等待绑定更新,或者是否有任何保证一个绑定在另一个之前更新?我是否希望编码以使绑定更新的顺序无关紧要?目前我使用依赖属性更改回调来执行各种通常依赖于其他属性更新的东西
这是MSDN提供的代码,虽然它似乎不清楚它在做什么:
[SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
public void DoEvents()
{
DispatcherFrame frame = new DispatcherFrame();
Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background,
new DispatcherOperationCallback(ExitFrame), frame);
Dispatcher.PushFrame(frame);
}
public object ExitFrame(object f)
{
((DispatcherFrame)f).Continue = false;
return null;
}
Run Code Online (Sandbox Code Playgroud)
我刚刚注意到今天在DoEvents定义该方法的一些遗留代码中的类似实现。为什么我们需要这个以及将框架推送到调度程序上意味着什么?
我读过C#版本如下:
Application.Current.Dispatcher.Invoke(
DispatcherPriority.Background,
new Action(delegate { }));
Run Code Online (Sandbox Code Playgroud)
但是我无法弄清楚如何将空委托放入VB.NET,因为VB.NET似乎不支持匿名方法.想法?
编辑:可能是这个?
Application.Current.Dispatcher.Invoke(
DispatcherPriority.Background,
New Action(Sub()
End Sub))
Run Code Online (Sandbox Code Playgroud) 我正在编写一个C#winform应用程序,它启动第二个进程来执行shell命令,如"dir"和"ping".我重定向第二个进程的输出,以便我的应用程序可以接收命令结果.它大致工作正常.
唯一的问题是我的winform app作为一个整体接收命令行输出而不是逐行接收.例如,它必须等待外部"ping"命令完成(需要几秒或更长时间),然后立即接收整个输出(多行).
我想要的是应用程序实时接收cmdline输出,即通过行而不是块.这可行吗?
我正在使用此代码来读取输出:while((result = proc.StandardOutput.ReadLine())!= null)
但它不像我预期的那样工作.提前致谢.
编辑:这是我正在使用的代码:
System.Diagnostics.ProcessStartInfo procStartInfo = new
System.Diagnostics.ProcessStartInfo("cmd", "/c " + command);
procStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
// The following commands are needed to redirect the standard output.
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;
// Now we create a process, assign its ProcessStartInfo and start it
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo = procStartInfo;
proc.Start();
// Get the output into a string
string result;
try {
while ((result = proc.StandardOutput.ReadLine()) != null) …Run Code Online (Sandbox Code Playgroud) 我如何将 a 集中Inline在 a 中RichTextBox?
我FlowDocument从文本文件创建一个并将其加载到我的中,richTextBox1
并Inline根据 Button_click一个接一个地标记(重新创建FlowDocument)
richTextBox1.SelectAll();
richTextBox1.Selection.Text = "";
string text = System.IO.File.ReadAllText(file);
int iZeile = 0;
string[] split = text.Split(new string[] {"\r\n"},StringSplitOptions.None);
foreach (string s in split)
{
if (iZeile != 27)
{
paragraph.Inlines.Add(s + "\r\n"); // adds line added without marking
}
else
{
Run run = new Run(split[27]); // adds line with marking
run.Background = Brushes.Yellow;
paragraph.Inlines.Add(run);
paragraph.Inlines.Add("\r\n");
}
iZeile++;
}
FlowDocument …Run Code Online (Sandbox Code Playgroud) 有人给我发了电子邮件,询问我是否有WaitOneAndPumpWPF 的版本.目标是WaitHandle.WaitOne在同一堆栈帧上等待句柄(类似于)并在等待时泵送WPF Dispatcher事件.
我真的不认为这样的API应该用于任何生产代码,无论是WinForms还是WPF(可能除了UI自动化之外).WPF没有暴露WinForms的显式版本DoEvents,这是一个非常好的设计决策,考虑到DoEventsAPI一直在滥用的公平份额.
然而,这个问题本身很有意思,所以我将把它作为一个练习并发布任何我想出的答案.如果有兴趣,请随意发布您自己的版本.
我的应用程序具有数据绑定只读TextBox功能,作为捕获和显示其“记录的”活动的手段。每次要记录某些内容时,都会将其连接到绑定字符串。这对于有限数量的记录文本来说足够有效,但随着文本数量的增加,它(可以理解)会陷入困境。我在之前的问题中看到了建议:Efficient live log-viewer in WPF和What is a fast way to render a log view in WPF? 使用ListBox. 我可以做到这一点,但我会失去一个很好的功能 - 允许用户选择和复制任意文本块。还有其他解决办法吗?