【发布时间】:2017-08-28 23:17:17
【问题描述】:
在 WPF 中,我一直试图弄清楚如何保持视图依赖属性和其中一个视图模型的属性同步一段时间,但没有任何运气。我对该主题进行了相当多的研究,但没有一个建议的解决方案对我有用,我希望有人可以帮助我找到我所缺少的。
我尝试了这篇帖子中建议的许多事情,Twoway-bind view's DependencyProperty to viewmodel's property?,因为我读过的所有内容看起来都是最有希望的,但始终无法获得我想要的结果。
我编写了一个简单的程序来演示我遇到的问题。在其中,我将 MainWindowViewModel 中的属性 IntValue 设置为 2,然后将其绑定到在 UserControl IncrementIntView 中创建的依赖项属性。然后,当我按下 IncrementIntView 中的按钮时,它会将 IntValue 的值增加一。这在 UserControl 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 源。 Binding 应该只是IntValue="{Binding IntValue, Mode=TwoWay}",因为UpdateSourceTrigger=PropertyChanged也是默认值。
标签: c# wpf mvvm data-binding dependency-properties