【问题标题】:Invoking source property update on a non-UI thread in two-way data binding在双向数据绑定中调用非 UI 线程上的源属性更新
【发布时间】:2015-04-07 06:43:47
【问题描述】:

假设我在源(CLR 属性)和目标(UI 控件属性)之间有一个 WPF 双向数据绑定。现在无论何时更新目标属性,我都想在非 UI 线程(而不是 Dispatcher 线程)上更新源属性。在我的应用程序中,我使用的是 Rx (Reactive Extension) 调度程序,因此,我计划提供一个 Rx 调度程序来执行。

例如,如果我绑定以下对象的属性 Value 并且 UI 使用绑定更新属性,我希望在我提供的 Rx 调度程序上执行 Value 属性的设置器。

public class A : VMBase {  // VMBase provides the plumbing of INotifyPropertyChanged
    private string _Value;
    public string Value {
        get { return _Value; }
        set { SetField(ref _Value, value, () => Value); }
    }
}

可以修改源属性的设置器以将更新切换到另一个线程。

public class A : VMBase {  // VMBase provides the plumbing of INotifyPropertyChanged
    private string _Value;
    public string Value {
        get { return _Value; }
        set { GetScheduler().Schedule(() => SetField(ref _Value, value, () => Value)); }
    }
}

但是,在我的情况下,这是不切实际的,因为我需要让我的用户修改他们的代码。

谷歌搜索这个问题,我发现我可以创建一个自定义 WPF 绑定,如下所示:http://www.hardcodet.net/2008/04/wpf-custom-binding-class。但是,我找不到应该在哪里挂钩代码以调用 Rx 调度程序上的更新。

任何解决方案或提示?我也愿意接受基于 Reactive Extensions 或 Reactive UI 的解决方案。

谢谢。

【问题讨论】:

  • 您能否分享一些您正在尝试做的事情的信息? UI 将始终在 UI 线程上执行,绑定也是如此。我只是不清楚“在后台线程上执行”是什么意思。该对象只是没有绑定到线程......
  • 您好,感谢您的评论。我在上面更新了我的问题。希望它能让我更清楚我想要实现的目标。你可能想知道我为什么要切换线程。这是因为在我的应用程序中,我需要访问特定线程(!= UI 线程)上的所有视图模型类。
  • 您使用的是什么版本的框架?因为在非 ui 线程上触发的 4 个 INPC 事件后,Bindings 会自动将其编组到 UI 线程上。
  • 我使用的是 .NET 4.0。是的,我知道在非 UI 线程上触发的 INPC 事件会自动编组到 UI 线程上。

标签: .net wpf data-binding system.reactive reactiveui


【解决方案1】:

它可以引入更多工作,但您可以使用交互将 ViewModel 中的命令链接到控件上的事件。这应该允许您拦截导致 ViewModel 上的值更新的事件,并使用您喜欢的任何方法设置您的 Value 属性。在这里,我还使用了 MVVM Light 框架的“EventToCommand”,但如果你使用其他东西,你可以换成<i:InvokeCommandAction...

<UserControl 
...other namespaces, declarations, etc...
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity">

    <Grid>
        <Button>
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="Click">
                    <cmdextras:EventToCommand Command="{Binding Path=SomethingWentClickCommand}" />
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </Button>
    </Grid>

</UserControl>

重新配置它以适应您正在使用的任何控件/事件,然后您的代码隐藏/视图模型类需要一个名为 SomethingWentClickCommand 的 RelayCommand 来检索新值并相应地更新您的绑定属性。

【讨论】:

  • 嗨。我只想将 CLR 属性绑定到我的视图并拦截对属性设置器的调用。在我的情况下,在拦截之间创建命令是不切实际的。无论如何,谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-07
  • 1970-01-01
  • 1970-01-01
  • 2014-02-21
  • 2012-08-29
  • 1970-01-01
相关资源
最近更新 更多