某处缺少绑定

时间:2013-02-17 13:14:53

标签: data-binding mvvm combobox selecteditem itemssource

使用mvvm演示项目(不是作业)

  1. 继承ObservableCollection的类朋友
  2. Class Friends ToString是FirstName +" " +姓氏等
  3. 具有Friends和SelectedFriend属性的ViewModel
  4. ComboBox ItemsSource绑定到ViewModel Friends属性
  5. ComboBox SelectedItem绑定到ViewModel Friends属性
  6. TextBoxes文本绑定到ViewModel SelectedFriend.FirstName属性等
  7. 我做了以下更改

    1. 选择史蒂夫
    2. 更改为Stephen - 更改需要,因为如果数据已保存并重新加载,则会显示Stephen
    3. ComboBox仍然显示史蒂夫
    4. 删除ComboBox列表并选择Sara
    5. 删除ComboBox列表 - 显示Steve
    6. 从ComboBox列表中选择Steve
    7. ComboBox现在显示Stephen和FirstName TextBox
    8. 选择Sara
    9. 删除ComboBox列表,它显示Steve
    10. ComboBox列表在保存和重新加载数据之前不会更改
    11. 数据被持久保存到xml文件中。我错过了哪些内容,以便ComboBox列表显示对SelectedItem的更新更改?

      模型类

      using System;
      using System.Collections.Generic;
      using System.ComponentModel;
      using System.Linq;
      using System.Text;
      
      namespace MVVM_Example.Models
      {
          public enum Gender : int
          {
              None = 0,
              Male,
              Female
          }
      
          public class Friend : INotifyPropertyChanged
          {
              private string _firstName;
      
              public string FirstName 
              {
                  get { return _firstName; }
                  set
                  {
                      if (_firstName != value)
                      {
                          _firstName = value;
                          OnPropertyChanged("FirstName");
                      }
                  }
              }
      
              public string LastName { get; set; }
              public DateTime HireDate { get; set; }
              public Gender Gender { get; set; }
              public bool IsContractor { get; set; }
              public string FullName { get { return string.Format("{0}, {1}", LastName, FirstName); } }
      
              public override string ToString()
              {
                  return string.Format("{0} {1}: Hired {2}, Gender {3}, Status: {4}", FirstName, LastName, HireDate.ToString("MMM dd, yyyy"), Gender, IsContractor ? "Contractor" : "Employee");
              }
      
              #region INotifyPropertyChanged Members
      
              public event PropertyChangedEventHandler PropertyChanged;
      
              protected void OnPropertyChanged(string propertyName)
              {
                  PropertyChangedEventHandler handler = PropertyChanged;
                  if (handler != null)
                  {
                      handler(this, new PropertyChangedEventArgs(propertyName));
                  }
              }
      
              #endregion
          }
      }
      
      using System;
      using System.Collections.Generic;
      using System.Collections.ObjectModel;
      using System.ComponentModel;
      using System.Linq;
      
      using MVVM_Example.Models;
      
      namespace MVVM_Example.Models
      {
          public class Friends : ObservableCollection<Friend>
          {
              public Friends()
                  : this(loadFriends())
              {
              }
      
              public Friends(List<Friend> friends)
                  : this(friends.ToArray())
              {
              }
      
              public Friends(IEnumerable<Friend> friends)
                  : base(friends)
              {
              }
      
              public static implicit operator Friends(List<Friend> friends)
              {
                  return new Friends(friends);
              }
      
              public Friends Sort()
              {
                  return this.Cast<Friend>().OrderBy(f => f.LastName).ThenBy(f => f.FirstName).ThenByDescending(f => f.HireDate).ToList();
              }
      
              private static List<Friend> loadFriends()
              {
                  return new List<Friend>
                  {
                      new Friend { FirstName = "Steve", LastName = "Wilson", Gender = Gender.Male, HireDate = new DateTime(2004, 3, 12), IsContractor = false },
                      new Friend { FirstName = "Adam", LastName = "Flowers", Gender = Gender.Male, HireDate = new DateTime(2012, 12, 28), IsContractor = false },
                      new Friend { FirstName = "Sara", LastName = "Fennema", Gender = Gender.Female, HireDate = new DateTime(2006, 8, 15), IsContractor = false },
                      new Friend { FirstName = "Gary", LastName = "Winey", Gender = Gender.Male, HireDate = new DateTime(2012, 4, 6), IsContractor = true },
                  }.OrderBy(f => f.LastName).ThenBy(f => f.FirstName).ToList();
              }
          }
      }
      

      视图模型

      using System;
      using System.Collections.Generic;
      using System.Collections.ObjectModel;
      using System.Collections.Specialized;
      using System.ComponentModel;
      using System.IO;
      using System.Linq;
      using System.Windows;
      using System.Windows.Controls;
      using System.Windows.Input;
      using System.Xml;
      using System.Xml.Serialization;
      
      using MVVM_Example.Models;
      
      namespace MVVM_Example.ViewModels
      {
          public class FriendsViewModel : INotifyPropertyChanged
          {
              #region Properties
      
              #region AreFriendsLoaded
      
              public bool AreFriendsLoaded
              {
                  get { return _areFriendsLoaded; }
                  private set
                  {
                      if (_areFriendsLoaded != value)
                      {
                          _areFriendsLoaded = value;
                          OnPropertyChanged("AreFriendsLoaded");
                      }
                  }
              }
              private bool _areFriendsLoaded;
      
              #endregion
      
              #region Friends
      
              public Friends Friends
              {
                  get { return _friends; }
                  private set
                  {
                      if (_friends != value)
                      {
                          _friends = value;
                          OnPropertyChanged("Friends");
                          HasFriends = value != null && value.Count > 0;
                      }
                  }
              }
              private Friends _friends;
      
              #endregion
      
              #region HasFriends
      
              public bool HasFriends 
              { 
                  get { return _hasFriends; }
                  private set
                  {
                      if (_hasFriends != value)
                      {
                          _hasFriends = value;
                          OnPropertyChanged("HasFriends");
                      }
                  }
              }
              private bool _hasFriends;
      
              #endregion
      
              #region SelectedFriend
      
              public Friend SelectedFriend
              {
                  get { return _selectedFriend; }
                  set
                  {
                      if (_selectedFriend != value)
                      {
                          _selectedFriend = value;
                          OnPropertyChanged("SelectedFriend");
                          transferData(true);
                      }
                  }
              }
              private Friend _selectedFriend;
      
              #endregion
      
              #region FirstName
      
              public string FirstName
              {
                  get { return _firstName; }
                  set
                  {
                      if (_firstName != value)
                      {
                          _firstName = value;
                          OnPropertyChanged("FirstName");
                          transferData("FirstName");
                      }
                  }
              }
              private string _firstName;
      
              #endregion
      
              #endregion
      
              #region Constructors
      
              public FriendsViewModel()
                  : base()
              {
                  verifyFriends();
              }
      
              #endregion
      
              #region Methods
      
              protected virtual void DeleteSelectedFriend()
              {
                  if (Friends.Contains(SelectedFriend))
                  {
                      Friends.Remove(SelectedFriend);
                  }
              }
      
              private void transferData(bool fromSelectedFriend)
              {
                  transferData(fromSelectedFriend, null);
              }
      
              private void transferData(string propertyName)
              {
                  transferData(false, propertyName);
              }
      
              private void transferData(bool fromSelectedFriend, string propertyName)
              {
                  if (fromSelectedFriend)
                  {
                      FirstName = SelectedFriend == null ? null : SelectedFriend.FirstName;
                  }
                  else if (SelectedFriend != null)
                  {
                      if (propertyName == null)
                      {
                          throw new InvalidOperationException("Missing propertyName argument in transferData method.");
                      }
      
                      switch (propertyName.Trim().ToLowerInvariant())
                      {
                          case "firstname":
                              SelectedFriend.FirstName = FirstName;
                              break;
                          default:
                              throw new InvalidOperationException(string.Format("Unexpected property name '{0} in transferData method.", propertyName));
                      }
                  }
              }
      
              private void verifyFriends()
              {
                  if (Friends == null)
                  {
                      Friends = new Friends();
                  }
              }
      
              #endregion
      
              #region INotifyPropertyChanged Members
      
              public event PropertyChangedEventHandler PropertyChanged;
      
              protected void OnPropertyChanged(string propertyName)
              {
      
                  PropertyChangedEventHandler handler = PropertyChanged;
                  if (handler != null)
                  {
                      handler(this, new PropertyChangedEventArgs(propertyName));
                  }
              }
      
              #endregion
          }
      }
      

      查看 - UserControl

      <UserControl x:Class="MVVM_Example.Views.FriendsView"
                   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" 
                   xmlns:j2a="http://j2associates.com/MVVMBase"
                   xmlns:sys="clr-namespace:System;assembly=mscorlib"
                   xmlns:vms="clr-namespace:MVVM_Example.ViewModels"
                   mc:Ignorable="d" 
                   d:DesignHeight="320" d:DesignWidth="400" Name="userControl">
      
          <UserControl.DataContext>
              <vms:FriendsViewModel />
          </UserControl.DataContext>
      
          <Grid Margin="5">
              <StackPanel>
                  <DockPanel LastChildFill="False">
                      <Label DockPanel.Dock="Top" Content="Friends" />
                      <ComboBox DockPanel.Dock="Bottom" Name="friendsComboBox" Margin="0,5,0,0" ToolTipService.ShowOnDisabled="True" VerticalContentAlignment="Center" 
                                ItemsSource="{Binding Friends}" SelectedItem="{Binding SelectedFriend}" IsEnabled="{Binding HasFriends}" />
                  </DockPanel>
      
                  <GroupBox Header="Selected Friend" Margin="0,5,0,0">
                      <Grid>
                          <Grid.RowDefinitions>
                              <RowDefinition Height="auto"/>
                              <RowDefinition Height="auto"/>
                              <RowDefinition Height="auto"/>
                              <RowDefinition Height="auto"/>
                              <RowDefinition Height="auto"/>
                          </Grid.RowDefinitions>
                          <Grid.ColumnDefinitions>
                              <ColumnDefinition Width="auto"/>
                              <ColumnDefinition/>
                          </Grid.ColumnDefinitions>
      
                          <Label Grid.Row="0" Grid.Column="0" Content="First Name" Margin="10,5,0,0" />
                          <Label Grid.Row="1" Grid.Column="0" Content="Last Name" Margin="10,5,0,0" />
                          <Label Grid.Row="2" Grid.Column="0" Content="Hire Date" Margin="10,5,0,0" />
                          <Label Grid.Row="3" Grid.Column="0" Content="Gender" Margin="10,5,0,0" />
                          <Label Grid.Row="4" Grid.Column="0" Content="Contractor" Margin="10,5,0,0" />
      
                          <TextBox Grid.Row="0" Grid.Column="1" Margin="5,5,0,0" VerticalContentAlignment="Center" 
                                   Text="{Binding FirstName, UpdateSourceTrigger=PropertyChanged, TargetNullValue=Undefined}" />
                          <TextBox Grid.Row="1" Grid.Column="1" Margin="5,5,0,0" VerticalContentAlignment="Center" 
                                   Text="{Binding SelectedFriend.LastName, UpdateSourceTrigger=PropertyChanged, FallbackValue=Undefined}" />
                          <DatePicker Grid.Row="2" Grid.Column="1" Margin="5,5,0,0" VerticalContentAlignment="Center" 
                                      SelectedDate="{Binding SelectedFriend.HireDate}" />
                          <TextBox Grid.Row="3" Grid.Column="1" Margin="5,5,0,0" VerticalContentAlignment="Center" 
                                   Text="{Binding SelectedFriend.Gender, UpdateSourceTrigger=PropertyChanged, FallbackValue=Undefined}" />
                          <CheckBox Grid.Row="4" Grid.Column="1" VerticalAlignment="Center" Margin="5,5,0,0" VerticalContentAlignment="Center" 
                                    IsChecked="{Binding SelectedFriend.IsContractor, FallbackValue={x:Null}}" />
                      </Grid>
                  </GroupBox>
      
                  <DockPanel LastChildFill="False">
                      <Button DockPanel.Dock="Left" Content="Save data" Margin="5,5,0,0" Width="70" Click="saveDataButton_Click" />
                  </DockPanel>
              </StackPanel>
          </Grid>
      </UserControl>
      

      ViewModel Code Behind - 使用事件而不是命令来最小化显示的代码

          private void saveDataButton_Click(object sender, RoutedEventArgs e)
          {
              string path = Directory.GetCurrentDirectory();
              path = new DirectoryInfo(Path.Combine(path, "..\\..\\Data\\friends.xml")).FullName;
      
              // Create a new file stream to write the serialized object to a file.
              using (TextWriter fileStreamWriter = new StreamWriter(path))
              {
                  // Create a new XmlSerializer instance with the type.
                  XmlSerializer serializer = new XmlSerializer(typeof(Friends));
                  serializer.Serialize(fileStreamWriter, ((MVVM_Example.ViewModels.FriendsViewModel)DataContext).Friends);
      
                  // Cleanup.
                  fileStreamWriter.Close();
              }
      
              MessageBox.Show(File.ReadAllText(path), "Data Saved", MessageBoxButton.OK, MessageBoxImage.Information);
          }
      

      主窗口

      <Window x:Class="MVVM_Example.MainWindow"
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              xmlns:views="clr-namespace:MVVM_Example.Views"
              Title="Main Window" Height="350" Width="425">
          <Grid>
              <views:FriendsView x:Name="friendsView1" />
          </Grid>
      </Window>
      

0 个答案:

没有答案