2015-06-04 2 views
-1

Привет Я пытаюсь изучить простую привязку данных в wpf. Я попробовал, и я не удается .. посоветуете пути ..Простая привязка данных в приложении 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 будет автоматически обновляться, как только я ввожу имя в текстовых полях.

Теперь мой файл отделенного кода выглядит следующим образом:

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

Установка DataContext, чтобы указать окно само будет решать непосредственную проблему:

public MainWindow() 
{ 
    InitializeComponent(); 
    this.DataContext = this; 
} 

Пути в связывании выражений в Xaml все относительно 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 (обратите внимание на изменение в первый и последний свойства имен!):

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"/> 
+0

Теперь, когда вы отвлекли мой взгляд на MVVM, я попробовал решение, которое вы предложили. Я создал два класса: 1. Person 2. PersonViewModel. Но при запуске кода он показывает исключение в строках «person in person.FirstName is null» .. Дело в том, что во время инициализации метка запрашивает контент и этот код выполняется. поскольку лицо не инициализировано, возникает исключение. Лицо лица; общественная строка ПолноеИмя { получить { обратный string.Format ("{0} {1}", person.FirstName, person.LastName); } } – Ashutosh

+0

Пожалуйста, укажите мне соответствующий учебник/учебный материал MVVM. С уважением – Ashutosh

+0

@ facebook-1069905816372422 Я исправил ошибку в классе PersonViewModel. Учебное пособие и ссылки на исследования не относятся к теме «Переполнение стека». Используйте веб-поиск, чтобы найти ресурсы. –

Смежные вопросы