在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