将 ViewModel 的属性绑定到 UserControl 的子控件和自身的 DependencyProperty
Posted
技术标签:
【中文标题】将 ViewModel 的属性绑定到 UserControl 的子控件和自身的 DependencyProperty【英文标题】:Bind ViewModel's property to UserControl's child control and itself DependencyProperty 【发布时间】:2021-09-22 05:37:20 【问题描述】:我想要做的是将我的用户控件的标签绑定到 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。
在主窗口中使用 Unit 的用户控件:
<DockPanel DataContext="Binding UnitVm, Source=StaticResource Locator">
<Viewbox
<Label x:Name="lblVolt" Content="Binding VoltInVm" />
</Viewbox>
</DockPanel>
lblVolt 绑定到 UnitVm 上下文可以正确更新新的电压值。 但是如何绑定到单位中 Volt 的 DependencyProperty 呢? 这是正确的方法吗?
提前致谢。
婷
【问题讨论】:
不确定您的实际问题是什么。你可以像<local:Unit Volt="Binding VoltInVm"/>
这样使用你的控件。在控件的 XAML 中,您将使用 "Binding Volt, RelativeSource=RelativeSource AncestorType=UserControl"
。
谢谢。我会试试看。我的问题是要知道视图模型中的绑定属性何时发生变化,因此我可以拦截它并做更多的事情(而不是更新标签的内容,这实际上是自动完成的,不是我自己完成的,我自己也不知道或可定制)。在此示例中添加 DependencyProperty 是为了使用 OnVoltChanged 方法,如果我正确绑定,该方法是视图模型中数据更改的通知 - 这是我的直接问题,我绑定到我的用户控件内的标签已经可以了。跨度>
【参考方案1】:
视图模型属性设置器未正确实现。
它应该如下所示,即使用正确的属性名称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"/>
Volt
依赖属性的 PropertyChangedCallback 将在每次 VoltInVm
属性更改其值时被调用。
但是不清楚依赖属性注册中的(o, e) => ((Unit)o).OnVoltChanged(o, e)
应该是什么。它当然应该是这样的:
(o, e) => ((Unit)o).OnVoltChanged((int)e.NewValue)
并且应该使用int
参数而不是double
声明方法:
private void OnVoltChanged(int volt) ...
或者 - 当然更好 - 在控件和视图模型中将所有电压属性类型更改为 double
。
【讨论】:
以上是关于将 ViewModel 的属性绑定到 UserControl 的子控件和自身的 DependencyProperty的主要内容,如果未能解决你的问题,请参考以下文章
如何将 WPF DataGrid DataColumns 可见性绑定到 UserControl 的 ViewModel 上的属性?
Kendo UI - 如何使用 Kendo MVVM 将选中的属性(属性)和处理复选框的单击事件绑定到 viewModel
如何将listview项绑定绑定到页面的Viewmodel?
将 StackLayout 绑定到 ViewModel 不起作用