【发布时间】:2014-07-24 10:12:17
【问题描述】:
我有一个EditorViewModel,其中包含一个 AvalonEditor 控件。我绑定到Document 的SelectionLength 和SelectionStart 属性,每个人都很高兴;我可以用鼠标选择文本来更新代码隐藏值,反之亦然。这是问题所在,我正在调用一个 C++ DLL,它通过回调将错误编组回调用 C# 代码,这也很有效。执行此操作的代码是
// Note, I need the call back to run on the main UI thread.
TaskScheduler scheduler = TaskScheduler.FromCurrentSynchronizationContext();
Callbacks.CompilerErrorCallback =
(message, documentPath, lineNumber) =>
{
string path = String.Empty;
Task.Factory.StartNew(async () =>
{
// Open the erronious file and scroll to line.
path = Path.Combine(
WorkingDirectory, String.Format("GDLCode\\{0}", documentPath));
Open(path);
//EditorViewModel evm = GetOpenEditorViewModels()
// .FirstOrDefault(vm => vm.FullFilePath.CompareNoCase(path));
//if (evm != null)
//{
// ActivateItem(evm);
// evm.SelectLine(lineNumber + 1);
//}
// Display error.
await dialogManager.ShowDialog<MessageDialogResult>(
new MessageBoxViewModel("GDECore Logic Compilation Error",
message,
settings));
return;
}, CancellationToken.None,
TaskCreationOptions.None,
scheduler);
};
// Run the C++ code below and pass in the `Callbacks.CompilerErrorCallback` object.
在EditorViewModel我有
public void SelectLine(int lineNumber)
{
DocumentLine line = Document.GetLineByNumber(lineNumber);
SelectionStart = line.Offset;
SelectionLength = line.Length;
}
编译器(C++ 代码)遇到编译错误并使用回调。这应该打开有问题的代码文件并突出显示有问题的行。回调有效且参数正确,但是注释掉的代码(应该选择有问题的行)不起作用。它进入SelectLine,并在设置SelectionLength throws 和ArgumentOutOfRangeException 从AvalonEdit;看起来EditorViewModel 没有绑定到底层的 AvalonEditor 控件。
但是,当我将有问题的代码注释掉并添加一个按钮以在打开代码文件后“手动”进行选择时
public void Test()
{
EditorViewModel evm = GetOpenEditorViewModels().FirstOrDefault();
if (evm != null)
{
ActivateItem(evm);
evm.SelectLine(1);
}
}
选择工作正常。为什么 AvalonEditor 控件似乎没有在回调中立即绑定到我的属性,我在做什么显然是错误的?
【问题讨论】:
-
这是线程问题吗?回调是否肯定被编组到 GUI 线程?
-
回调在 非-GUI 线程上,因此我必须使用
Task.Factory和同步上下文来将代码放回 GUI 线程上。
标签: c# c++ asynchronous mvvm binding