将 ViewModel 的 属性 绑定到 UserControl 的子控件及其自身 DependencyProperty

Bind ViewModel's property to UserControl's child control and itself DependencyProperty

我想做的是将我的用户控件的标签绑定到 ViewModel 中的 属性 值。 但我也想在标签更改时收到通知(并做其他工作,如提取标签的新值以修改网格宽度等)。

如何操作?

我做的是:

有一个带有电压 属性 的视图模型,这就是我想要显示的内容。

UnitVm.cs

    private int m_V;
    public int VoltInVm
    {
        get
        { return m_V;  }
        set
        {
            if (m_V != value)
            {        
                Set<int>(ref m_V, value, nameof(Volt)); 
            }
        }
    }

和我的用户控件:Unit.cs

public partial class Unit : UserControl
{
    public static readonly DependencyProperty VoltProperty =
                      DependencyProperty.Register("Volt", typeof(int), typeof(Unit),  
                    new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.AffectsRender, (o, e) => ((Unit)o).OnVoltChanged(o, e)));

    private void OnVoltChanged(double dVolt)
    {
            double dWidth;
            if (double.TryParse(strVal, out dWidth))
            {
                dWidth = dVolt / 380 * 100;

                if (dWidth > 100)
                    dWidth = 100;

                gridVolt.ColumnDefinitions[0].Width = new GridLength(dWidth, GridUnitType.Star);
                gridVolt.ColumnDefinitions[1].Width = new GridLength(100 - dWidth, GridUnitType.Star);
            }           
    }
    public int Volt
    {
        get { return (int)GetValue(VoltProperty); }
        set
        {
            SetValue(VoltProperty, value);
        }
    }

定义了VoltProperty的DependencyProperty,我要做的工作写在OnVoltChanged里面

我的意思是当接受来自 ViewModel 的更改时,我可以调用 OnVoltChanged。

在主window中使用Unit的用户控件:

    <DockPanel DataContext="{Binding UnitVm, Source={StaticResource Locator}}">
        <Viewbox 
            <Label x:Name="lblVolt" Content="{Binding VoltInVm}" />
        </Viewbox>
    </DockPanel>

lblVolt 绑定到 UnitVm 上下文可以正确更新新的电压值。 但是如何绑定到Unit中Volt的DependencyProperty呢? 这是正确的方法吗?

提前致谢。

视图模型 属性 setter 未正确实现。

它应该如下所示,即使用正确的 属性 名称 nameof(VoltInVm) 并且可能在调用 Set 之前不检查 m_V != value,因为这已经由Set 方法。

private int voltInVm;

public int VoltInVm
{
    get { return voltInVm;  }
    set { Set<int>(ref voltInVm, value, nameof(VoltInVm)); }
}

当您现在绑定 UserControl 的 属性 时

<local:Unit Volt="{Binding VoltInVm}"/>

每次 VoltInVm 属性 更改其值时,都会调用 Volt 依赖项 属性 的 PropertyChangedCallback。

然而,不清楚 属性 注册中的 (o, e) => ((Unit)o).OnVoltChanged(o, e) 应该是什么。它应该看起来像这样:

(o, e) => ((Unit)o).OnVoltChanged((int)e.NewValue)

并且该方法应该使用 int 参数而不是 double:

来声明
private void OnVoltChanged(int volt) ...

或者 - 当然更好 - 在控件和视图模型中将所有电压 属性 类型更改为 double