我在将某些值从视图更新到viewmodel时遇到问题。我有一个类(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));
}
}
我在ComplexType
(来自MvvmLight库的MainViewModel
)中使用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上找到答案,但我不能。也许我没有点击关键字。你知道我做错了吗?
答案 0 :(得分:1)
TextBox
中的UserControl
应绑定到Value
属性:
<TextBox x:Name="value1Textbox" Text="{Binding Value, RelativeSource={RelativeSource AncestorType=UserControl}}"/>
然而,您在TextBox
中输入的值不会传播回源。