【问题标题】:Writing back a dependency property value to the view model in two-way binding在双向绑定中将依赖属性值写回视图模型
【发布时间】:2016-07-14 16:55:14
【问题描述】:

我正在实现一个 wpf 控件,它提供了 xaml 和在 Web 浏览器中运行的 Google 地图之间的一些通用绑定。目前,绑定是单向的并且工作正常。

接下来我需要做的是在指定双向绑定时将值写回视图模型。我开始的属性是谷歌地图的缩放。当它在浏览器中更改时,我可以在页面上运行 js,以新的缩放级别回调我的 C# 代码。

如果选择双向绑定,向 DP 提供这个新值的正确方法是什么,例如它会更新视图模型的缩放级别?

我当前的缩放级别 DP 代码:

#region ZoomProperty

    //Called from the web page
    private JSValue MapZoom_OnMapZoomChanged(JSValue[] arguments) {
        string zoom = arguments[0];

        //where do I set the zoom so that the view model bound property is updated?
        return null;
    }

public static readonly DependencyProperty ZoomProperty =
    DependencyProperty.Register("Zoom", typeof(string), typeof(GoogleMap), new FrameworkPropertyMetadata(string.Empty, OnZoomPropertyChanged), OnZoomPropertyValidate);

public string Zoom {
    get { return (string)GetValue(ZoomProperty); }
    set { SetValue(ZoomProperty, value); }
}

private static bool OnZoomPropertyValidate(object value) {
    return value is string;
}

private static void OnZoomPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e) {
    GoogleMap control = source as GoogleMap;
    control.SetZoom(e.NewValue.ToString());
}

private string zoom;
public void SetZoom(string value) {
    if (!googleMapPageReady) {
        zoom = value;
        return;
    }

    webControl.ExecuteJavascript(string.Format("setZoom({0})", zoom));
}

#endregion

【问题讨论】:

  • 请注意,您还可以使用 Register 方法的另一个重载设置 FrameworkPropertyMetadataOptions.BindsTwoWayByDefault 标志,以使依赖项属性默认为双向绑定。

标签: c# wpf xaml dependency-properties


【解决方案1】:

除非我忽略了什么,否则你只需要这样做:

private JSValue MapZoom_OnMapZoomChanged(JSValue[] arguments)
{
    string newZoom= arguments[0];
    this.Zoom = newZoom; // here
    return null;
}

设置了依赖属性模式,以便从外部您可以将 Zoom 视为普通的 c# 属性(setter 和 getter)。如果您查看该属性的 setter,它会调用 SetValue(),它位于 DependencyObject 基类上,并且会神奇地将更改通知绑定引擎(另请参阅:Register()

更新

当地图首先提供更改时,防止更改将更新发送到地图的简单方法:

private bool IsMapUpdateSuppressed = false;

private JSValue MapZoom_OnMapZoomChanged(JSValue[] arguments)
{
    string newZoom= arguments[0];
    this.IsMapUpdateSuppressed = true;
    this.Zoom = newZoom;
    this.IsMapUpdateSuppressed = false;
    return null;
}

private static void OnZoomPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
    GoogleMap control = source as GoogleMap;
    if (!control.IsMapUpdateSuppressed)
    {
        control.SetZoom(e.NewValue.ToString());
    }
}

这允许 DP 值像往常一样更改、处理和通知绑定引擎,但只是阻止了对 SetZoom 的调用

【讨论】:

  • 我想这是我的困惑 - 我是否需要防止 OnZoomPropertyChanged 在这种情况下再次被调用?缩放值来自地图,因此无需再次设置。
  • 不会再次调用 OnZoomPropertyChanged,除非 Zoom 属性的值确实发生了变化。
  • 您在 xaml 中实际绑定的是什么?
  • 我认为我的问题(第一次涉足 DP)是 c# 中用于缩放的 DP 是实际缩放的代理值(由地图保存。)我需要考虑如何处理这个。
  • 我明白了 - 您担心在 it 是发送更改的人之后将缩放更改转发回地图(因此不需要通知) ?
猜你喜欢
  • 1970-01-01
  • 2012-04-13
  • 2013-02-14
  • 1970-01-01
  • 1970-01-01
  • 2012-11-04
  • 2014-08-24
  • 1970-01-01
相关资源
最近更新 更多