Reputation: 23831
I have an EditorViewModel
which contains an AvalonEditor control. I bind to the SelectionLength
and SelectionStart
properties of Document
and everyone is happy; I can select text with both the mouse which updates the code-behind values and visa versa. Here is the issue, I am calling a C++ DLL which marshals errors back to the calling C# code via a callback, this too works well. The code to do this is
// 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.
In EditorViewModel
I have
public void SelectLine(int lineNumber)
{
DocumentLine line = Document.GetLineByNumber(lineNumber);
SelectionStart = line.Offset;
SelectionLength = line.Length;
}
The compiler (the C++ code) hits a compilation error and uses the callback. This is supposed to open the offending code file and highlight the offending line. The callback works and the parameters are right however, the code which is commented (which is supposed to select the offending line) out does not work. It goes into SelectLine
and upon setting SelectionLength
throws and ArgumentOutOfRangeException
from AvalonEdit; it looks like the EditorViewModel
is not bound to the underlying AvalonEditor control.
However, when I comment the offending code out and add a button to do the selection 'manually' after the code file has been opened
public void Test()
{
EditorViewModel evm = GetOpenEditorViewModels().FirstOrDefault();
if (evm != null)
{
ActivateItem(evm);
evm.SelectLine(1);
}
}
The selection works fine. Why is it that the AvalonEditor control does not seem to be binding to my properties immediately in the callback, is there anything I am doing that is obviously wrong?
Upvotes: 0
Views: 74
Reputation: 25641
Can you confirm it is being called back on the UI thread?
What does the threads window in VS debugger tell you if you have a bresak point in the Task?
I would consider using the Dispatcher.Invoke method instead of Task:
Application.Current.Dispatcher.Invoke(() =>
{
// to do something
});
Personally I would look at using Reactive Extensions (Rx .Net) to do all this, it has the ability to manage schedulers much better than Task IMO.
Upvotes: 1