【发布时间】:2018-04-23 14:53:15
【问题描述】:
我在将某些值从视图更新到视图模型时遇到问题。我有一个类 (ComplexType) 实现了 INotifyPropertyChanged 并具有一些属性:
public class ComplexType : INotifyPropertyChanged
{
private bool enabled = false;
private string name = "No name";
private int value = 0;
public bool Enabled
{
get { return this.enabled; }
set
{
if (this.enabled == value) return;
this.enabled = value;
this.RaisePropertyChanged();
}
}
public string Name
{
get { return this.name; }
set
{
if (this.name == value) return;
this.name = value;
this.RaisePropertyChanged();
}
}
public int Value
{
get { return this.value; }
set
{
if (this.value == value) return;
this.value = value;
this.RaisePropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged([CallerMemberName] string propertyName = null)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
我在MainViewModel 中使用ComplexType(来自MvvmLight 库的ViewModelBase):
public class MainViewModel : ViewModelBase
{
private string simpleType1 = "Not set";
public string SimpleType1
{
get { return this.simpleType1; }
set
{
if (this.simpleType1 == value) return;
this.simpleType1 = value;
this.RaisePropertyChanged();
}
}
private ComplexType complexType1 = null;
public ComplexType ComplexType1
{
get { return this.complexType1; }
set
{
if (this.complexType1 == value) return;
this.complexType1 = value;
this.RaisePropertyChanged();
}
}
private RelayCommand saveCommand;
public RelayCommand SaveCommand
{
get
{
return this.saveCommand ?? (this.saveCommand = new RelayCommand(this.ExecuteSaveCommand));
}
}
private void ExecuteSaveCommand()
{
Console.WriteLine(this.SimpleType1);
Console.WriteLine(this.ComplexType1.Value);
}
public MainViewModel()
{
this.SimpleType1 = "Simple type 1";
this.ComplexType1 = new ComplexType()
{
Enabled = true,
Name = "Complex type 1",
Value = 111
};
}
}
我想使用用户控件 (ComplexControl) 来显示 ComplexType 数据。
XAML:
<UserControl x:Class="MvvmTest.ComplexControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<StackPanel>
<CheckBox x:Name="checkbox1"/>
<TextBlock x:Name="name1TextBlock"/>
<TextBox x:Name="value1Textbox"/>
</StackPanel>
</UserControl>
后面的代码:
public partial class ComplexControl : UserControl
{
public static readonly DependencyProperty EnabledProperty =
DependencyProperty.Register("Enabled", typeof(bool), typeof(ComplexControl),
new PropertyMetadata(false, new PropertyChangedCallback(ComplexControl.EnabledPropertyChanged)));
public bool Enabled
{
get { return (bool)this.GetValue(ComplexControl.EnabledProperty); }
set { this.SetValue(ComplexControl.EnabledProperty, value); }
}
private static void EnabledPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((ComplexControl)d).checkbox1.IsChecked = (bool)e.NewValue;
}
public static readonly DependencyProperty ParameterNameProperty =
DependencyProperty.Register("ParameterName", typeof(string), typeof(ComplexControl),
new PropertyMetadata("No name", new PropertyChangedCallback(ComplexControl.ParameterPropertyChanged)));
public string ParameterName
{
get { return (string)this.GetValue(ComplexControl.ParameterNameProperty); }
set { this.SetValue(ComplexControl.ParameterNameProperty, value); }
}
private static void ParameterPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((ComplexControl)d).name1TextBlock.Text = (string)e.NewValue;
}
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(int), typeof(ComplexControl),
new PropertyMetadata(0, new PropertyChangedCallback(ComplexControl.ValuePropertyChanged)));
public int Value
{
get { return (int)this.GetValue(ComplexControl.ValueProperty); }
set { this.SetValue(ComplexControl.ValueProperty, value); }
}
private static void ValuePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((ComplexControl)d).value1Textbox.Text = ((int)e.NewValue).ToString();
}
public ComplexControl()
{
InitializeComponent();
}
}
这是我的MainWindow:
XAML:
<Window x:Class="MvvmTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:MvvmTest"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<TextBox x:Name="textbox1" Text="{Binding SimpleType1}"/>
<local:ComplexControl Enabled="{Binding ComplexType1.Enabled}" ParameterName="{Binding ComplexType1.Name}"
Value="{Binding ComplexType1.Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<Button Content="Save!" Command="{Binding SaveCommand}"/>
</StackPanel>
</Window>
后面的代码:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new MainViewModel();
}
}
数据显示正确,但是当我更改绑定到ComplexType 的属性时出现问题。例如,如果我更改每个文本框中的 SimpleType1 和 ComplexType1.Value 文本,然后单击“保存!”按钮,我可以在控制台看到SimpleType1属性已经更新了值,但是ComplexType1.Value是初始值。
我试图在 StackOverflow 上找到答案,但我找不到。也许我没有用关键字打。你知道我做错了什么吗?
【问题讨论】:
-
checkbox1等根本没有绑定。为什么会这样,莱昂?