2016-04-13 29 views
0

RelayCommandを使用して最初のWPFプログラムをビルドしています。ユーザーを編集または作成するパラメータとして「User」オブジェクトを渡すためにクリックします。既存のユーザーはonClick fineに渡されますが、新しいユーザーの空白行に入力された情報は常にNULLプロパティを持ちます。ただし、オブジェクトがNULLかどうかを確認するテストでは、常にオブジェクトが存在しないことが示されます。どのようにオブジェクトがNULLではないが、ウィンドウに入力された内容は?誰でも新しいオブジェクトのバインディングに間違った点を見つけられますか?事前に多くの感謝!WPFオブジェクトはチェック時にNULLではないが、プロパティNULL

UserViewModelクラス:

public class UserViewModel : INotifyPropertyChanged 
{ 
    private string _FirstName; 
    public string FirstName 
    { 
     get { return _FirstName; } 
     set { _FirstName = value; NotifyPropertyChanged("FirstName"); } 
    } 

    private string _LastName; 
    public string LastName 
    { 
     get { return _LastName; } 
     set { _LastName = value; NotifyPropertyChanged("LastName"); } 
    } 

    private string _EMail; 
    public string EMail 
    { 
     get { return _EMail; } 
     set { _EMail = value; NotifyPropertyChanged("EMail"); } 
    } 

    private int _UserID; 
    public int UserID 
    { 
     get { return _UserID; } 
     set { _UserID = value; NotifyPropertyChanged("UserID"); } 
    } 

    private string _Position; 
    public string Position 
    { 
     get { return _Position; } 
     set { _Position = value; NotifyPropertyChanged("Position"); } 
    } 

    private DateTime? _EndDate; 
    public DateTime? EndDate 
    { 
     get { return _EndDate; } 
     set { _EndDate = value; NotifyPropertyChanged("EndDate"); } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    private void NotifyPropertyChanged(String info) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(info)); 
     } 
    } 
} 

UsersViewModelクラス:

public partial class UsersViewModel : INotifyPropertyChanged 
{ 
    public RelayCommand<object> editButton_Click_Command { get; set; } 

    public UsersViewModel() 
    { 
     editButton_Click_Command = new RelayCommand<object>(OneditButton_Click_Command); 
    } 

    private ObservableCollection<UserViewModel> _Users; 
    public ObservableCollection<UserViewModel> Users 
    { 
     get { return _Users; } 
     set { _Users = value; NotifyPropertyChanged("Users"); } 
    } 

    private void OneditButton_Click_Command(object obj) 
    { 
     var associatedViewModel = obj as UserViewModel; 
     string lastName = associatedViewModel.LastName; //Always NULL on new row entered in Window!!! 
     if (associatedViewModel == null) 
     { 
      //Never reached 
     } 
     if (obj == null) 
     { 
      //Never reached 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    private void NotifyPropertyChanged(String info) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(info)); 
     } 
    } 
} 

RelayCommand:メインウィンドウからUsersWindowを開く

public class RelayCommand<T> : ICommand 
{ 
    #region Fields 

    private readonly Action<T> _execute = null; 
    private readonly Predicate<T> _canExecute = null; 

    #endregion 

    #region Constructors 

    /// <summary> 
    /// Creates a new command that can always execute. 
    /// </summary> 
    /// <param name="execute">The execution logic.</param> 
    public RelayCommand(Action<T> execute) 
     : this(execute, null) 
    { 
    } 

    /// <summary> 
    /// Creates a new command with conditional execution. 
    /// </summary> 
    /// <param name="execute">The execution logic.</param> 
    /// <param name="canExecute">The execution status logic.</param> 
    public RelayCommand(Action<T> execute, Predicate<T> canExecute) 
    { 
     if (execute == null) 
      throw new ArgumentNullException("execute"); 

     _execute = execute; 
     _canExecute = canExecute; 
    } 

    #endregion 

    #region ICommand Members 

    public bool CanExecute(object parameter) 
    { 
     return _canExecute == null ? true : _canExecute((T)parameter); 
    } 

    public event EventHandler CanExecuteChanged 
    { 
     add 
     { 
      if (_canExecute != null) 
       CommandManager.RequerySuggested += value; 
     } 
     remove 
     { 
      if (_canExecute != null) 
       CommandManager.RequerySuggested -= value; 
     } 
    } 

    public void Execute(object parameter) 
    { 
     try 
     { 
      _execute((T)parameter); 
     } 
     catch 
     { 
      System.Windows.MessageBox.Show("Please enter values for the new entry."); 
     } 
    } 

    #endregion 
} 

UsersViewModel Usersvm = new UsersViewModel(); 
Usersvm.Users = new ObservableCollection<UserViewModel>(); 
Usersvm.Users.Add(new UserViewModel() { FirstName = "John", LastName = "Doe", EMail = "[email protected]", EndDate = new DateTime(2016, 2, 1), Position = "Developer", UserID = 1 }); 
new UsersWindow(Usersvm).Show(); 

UsersWindow.xaml.cs:

public partial class UsersWindow : Window 
{ 
    public UsersWindow(UsersViewModel uvm) 
    { 
     InitializeComponent(); 
     DataContext = uvm; 
    } 
} 

最後にXAML:

<Window x:Name="Base_V" 
    x:Class="DbEntities.UsersWindow" 
    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:DbEntities" 
    xmlns:ViewModels="clr-namespace:DbEntities" 
    xmlns:staticData="clr-namespace:DbEntities" 
    mc:Ignorable="d" 
    Title="UsersWindow" Height="Auto" Width="900"> 
    <Window.Resources> 
     <staticData:PositionsList x:Key="PositionsList" /> 
    </Window.Resources> 
    <Window.DataContext> 
     <ViewModels:UsersViewModel/> 
    </Window.DataContext> 
    <Grid> 
     <DataGrid Name="DataGrid1" ItemsSource="{Binding Users}" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" 
       ColumnWidth="*" AutoGenerateColumns="False"> 
      <DataGrid.Columns> 
       <DataGridTemplateColumn> 
        <DataGridTemplateColumn.CellTemplate> 
         <DataTemplate> 
          <Button Command="{Binding DataContext.editButton_Click_Command, ElementName=Base_V}" CommandParameter="{Binding}" >Edit</Button> 
         </DataTemplate> 
        </DataGridTemplateColumn.CellTemplate> 
       </DataGridTemplateColumn> 
       <DataGridTextColumn Header="User ID" Binding="{Binding UserID}" IsReadOnly="True" /> 
       <DataGridTextColumn Header="Last Name" Binding="{Binding LastName}" /> 
       <DataGridTextColumn Header="First Name" Binding="{Binding FirstName}" /> 
       <DataGridTextColumn Header="E-Mail" Binding="{Binding EMail}" /> 
       <DataGridTemplateColumn> 
        <DataGridTemplateColumn.HeaderTemplate> 
         <DataTemplate> 
          <Label Content="Position" /> 
         </DataTemplate> 
        </DataGridTemplateColumn.HeaderTemplate> 
        <DataGridTemplateColumn.CellTemplate> 
         <DataTemplate> 
          <ComboBox ItemsSource="{StaticResource PositionsList}" SelectedItem="{Binding Position}" /> 
         </DataTemplate> 
        </DataGridTemplateColumn.CellTemplate> 
       </DataGridTemplateColumn> 
       <DataGridTextColumn Header="End Date" Binding="{Binding EndDate, StringFormat={}{0:MM/dd/yyyy}}" /> 
      </DataGrid.Columns> 
     </DataGrid> 
    </Grid> 
</Window> 

答えて

0

ここでの答えは、DataGridが常にボタンクリックに元の値を送信していたことです。バインドされたテキストボックスを使用して単一のオブジェクトを編集できる新しいページにユーザーを誘導すると、問題が解決されます。

+0

これをどのように発見しましたか?私はあなたが少なくとも私が示唆した修正を加え、そのようなことを続けてくれることを願っています。私は**あなたが問題を発見したと仮定します** **私が指示した修正をした後。 – user34660

+0

この問題は、これまで私が以前に抱えていた問題から生じました。http://stackoverflow.com/questions/36555191/wpf-listbox-data-binding/36558782#36558782私はそのスレッドのポスターの1つで質問し、解決しました。あなたのお返事ありがとうございます!私はあなたが提案した変更を行い、それは完全に意味を成しています。 – jle

0
あなたは物事をやっている順序を逆に

。まず、objがnullかどうかを確認します。 nullでない場合の場合、それをassociatedViewModelに変換(キャスト)します。次に、associatedViewModelがnullであるかどうかを確認します。次に、associatedViewModelがでない場合(および唯一の場合)nullでなければ、associatedViewModel.LastNameを使用できます。いずれかがnullの場合は、もちろんエラーを発行してください。

nullではないはずのものがあると仮定して、問題を再現するのに必要な最小限のコードに減らします。

関連する問題