在WPF中,我一直在试图弄清楚如何保持一个视图依赖属性和它的一个视图模型的属性同步一段时间没有任何运气。我对这个主题进行了大量的研究,但是没有一个建议的解决方案适用于我,我希望有人能够帮助我找到我失踪的东西。WPF - 如何保持依赖项属性和视图模型属性同步?
我尝试了很多在这篇文章中建议的东西,Twoway-bind view's DependencyProperty to viewmodel's property?,因为我看过的所有东西看起来都是最有前途的,但从来没有能够得到我期待的结果。
我写了一个简单的程序来演示我遇到的问题。其中我将MainWindowViewModel中的属性IntValue设置为2,然后将其绑定到在UserControl IncrementIntView中创建的依赖项属性。然后当我在IncrementIntView中按下按钮时,它将IntValue的值增加1。这一切工作的用户控件IncrementIntView里面很好,但我无法弄清楚如何更新INTVALUE送回MainWindowViewModel,它保持设定为2
IncrementIntView.xaml.cs
public partial class IncrementIntView : UserControl
{
public int IntValue
{
get { return (int)GetValue(IntValueProperty); }
set { SetValue(IntValueProperty, value); }
}
public static readonly DependencyProperty IntValueProperty =
DependencyProperty.Register("IntValue", typeof(int), typeof(IncrementIntView),
new PropertyMetadata(-1, new PropertyChangedCallback(IntValueChanged)));
private static void IntValueChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
IncrementIntView detailGroup = dependencyObject as IncrementIntView;
if (e.NewValue != null)
{
detailGroup.ViewModel.IntValue = (int)e.NewValue;
}
}
public IncrementIntView()
{
InitializeComponent();
}
}
IncrementIntViewModel.cs
public class IncrementIntViewModel : ViewModelBase
{
private int intValue;
public int IntValue
{
get { return intValue; }
set { SetProperty(ref intValue, value); }
}
public IncrementIntViewModel()
{
incrementIntCommand = new Command(IncrementInt);
}
private Command incrementIntCommand;
public Command IncrementIntCommand { get { return incrementIntCommand; } }
public void IncrementInt()
{
IntValue++;
}
}
IncrementIntView.xaml
<UserControl.DataContext>
<local:IncrementIntViewModel x:Name="ViewModel" />
</UserControl.DataContext>
<Grid>
<StackPanel Orientation="Horizontal">
<Label Content="{Binding IntValue}" />
<Button Content="Increment" Command="{Binding IncrementIntCommand}" Width="75" />
</StackPanel>
</Grid>
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
MainWindowViewModel.cs
public class MainWindowViewModel : ViewModelBase
{
private int intValue = 2;
public int IntValue
{
get { return intValue; }
set { SetProperty(ref intValue, value); }
}
}
MainWindow.xaml
<Window.DataContext>
<local:MainWindowViewModel x:Name="ViewModel"/>
</Window.DataContext>
<Grid>
<StackPanel Margin="10">
<local:IncrementIntView IntValue="{Binding IntValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ElementName=ViewModel}" />
<Label Content="{Binding IntValue}" />
</StackPanel>
</Grid>
请注意'ElementName = ViewModel'完全是多余的。由于MainWindowViewModel实例已分配给Window的DataContext,因此不需要显式指定Binding源。绑定应该是'IntValue =“{Binding IntValue,Mode = TwoWay}”',因为'UpdateSourceTrigger = PropertyChanged'也是默认值。 – Clemens