【问题标题】:Binding Failure at Runtime Using MVVM使用 MVVM 在运行时绑定失败
【发布时间】: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


【解决方案1】:

你能确认它正在 UI 线程上被回调吗?

如果您的任务中有断点,VS 调试器中的线程窗口会告诉您什么?

我会考虑使用 Dispatcher.Invoke 方法而不是 Task:

Application.Current.Dispatcher.Invoke(() =>
{
   // to do something
});

我个人会考虑使用 Reactive Extensions (Rx .Net) 来完成这一切,它能够比 Task IMO 更好地管理调度程序。

【讨论】:

  • 我要到下周才能检查这个。我会尽快回复您...再次感谢您的宝贵时间。
猜你喜欢
  • 2014-07-12
  • 1970-01-01
  • 1970-01-01
  • 2013-05-06
  • 2013-05-28
  • 1970-01-01
  • 2014-11-09
  • 2019-03-20
  • 2016-01-21
相关资源
最近更新 更多