您好我正在尝试研究wpf中的简单数据绑定。我尝试过但没有成功..请提出方法..
<Window x:Class="WpfTestApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="250" Width="350">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="70"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="50"/>
<RowDefinition Height="50"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<Label Content="First Name" Grid.Row="0" Grid.Column="0" Height="25" HorizontalAlignment="Stretch"/>
<Label Content="Last Name" Grid.Row="1" Grid.Column="0" Height="25" HorizontalAlignment="Stretch"/>
<Label Content="Full Name" Grid.Row="2" Grid.Column="0" Height="25" HorizontalAlignment="Stretch"/>
<TextBox x:Name="fName" Text="{Binding FirstName, UpdateSourceTrigger=PropertyChanged}" Grid.Row="0" Grid.Column="1" Height="25" HorizontalAlignment="Stretch"/>
<TextBox x:Name="lName" Text="{Binding LastName, UpdateSourceTrigger=PropertyChanged}" Grid.Row="1" Grid.Column="1" Height="25" HorizontalAlignment="Stretch"/>
<Label x:Name="lblFullName" Content="{Binding FirstName}" Grid.Row="2" Grid.Column="1" Height="25" HorizontalAlignment="Stretch"/>
<Button x:Name="cmdCommand" Content="Command" Grid.Row="3" Grid.Column="1" Margin="2" VerticalAlignment="Center" HorizontalAlignment="Center" Click="cmdCommand_Click"/>
</Grid>
</Window>
现在你看,我希望在文本框中输入名称时,标签lblFullName会自动更新。
现在我的codebehind文件看起来像这样:
public partial class MainWindow : Window, INotifyPropertyChanged
{
private string _firstName;
public string FirstName
{
get { return _firstName; }
set
{
if (value != _firstName)
{
_firstName = value;
OnPropertyChanged("FirstName");
}
}
}
private string _lastName;
public string LastName
{
get { return _lastName; }
set
{
if (value != _lastName)
{
_lastName = value;
OnPropertyChanged("LastName");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Notifies objects registered to receive this event that a property value has changed.
/// </summary>
/// <param name="propertyName">The name of the property that was changed.</param>
protected virtual void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public MainWindow()
{
InitializeComponent();
}
private void cmdCommand_Click(object sender, RoutedEventArgs e)
{
lblFullName.Content = FirstName + " " + LastName;
}
}
不用说,即使点击命令按钮也不起作用......
有什么建议吗?
答案 0 :(得分:0)
将DataContext设置为指向窗口本身将解决当前问题:
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
}
Xaml中Binding表达式中的路径都是相对于控件的DataContext的,因此必须设置DataContext。
但是,我强烈建议您将名字和姓氏放在一个单独的类中(例如 PersonViewModel ),这样可以使代码更易于阅读和维护。
public class PersonViewModel : INotifyPropertyChanged
{
private string _firstName;
public string FirstName
{
get { return _firstName; }
set
{
if (value != _firstName)
{
_firstName = value;
OnPropertyChanged("FirstName");
}
}
}
private string _lastName;
public string LastName
{
get { return _lastName; }
set
{
if (value != _lastName)
{
_lastName = value;
OnPropertyChanged("LastName");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
var handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new PersonViewModel();
}
private void cmdCommand_Click(object sender, RoutedEventArgs e)
{
lblFullName.Content = FirstName + " " + LastName;
}
}
现在这段代码的最后一部分不再起作用了。有两种解决方案。
快速而肮脏的解决方案:
private void cmdCommand_Click(object sender, RoutedEventArgs e)
{
var person = this.DataContext as PersonViewModel;
if(person == null) return;
lblFullName.Content = string.Format("{0} {1}", person.FirstName, person.LastName);
}
更好的方法是,在尝试执行适当的MVVM时,在ViewModel中添加一个额外的属性(请注意First和Last名称属性的更改!):
public class PersonViewModel : INotifyPropertyChanged
{
public string FullName
{
get
{
return string.Format("{0} {1}", FirstName, LastName);
}
}
private string _firstName;
public string FirstName
{
get { return _firstName; }
set
{
if (value != _firstName)
{
_firstName = value;
OnPropertyChanged("FirstName");
OnPropertyChanged("FullName");
}
}
}
private string _lastName;
public string LastName
{
get { return _lastName; }
set
{
if (value != _lastName)
{
_lastName = value;
OnPropertyChanged("LastName");
OnPropertyChanged("FullName");
}
}
}
// remainder of the class remains the same
}
删除按钮及其单击处理程序。将标签绑定到这个新属性:
<Label Content="{Binding FullName}"
Grid.Row="2" Grid.Column="1"
Height="25" HorizontalAlignment="Stretch"/>