我正在使用RelayCommand构建我的第一个WPF程序并点击按钮以传递"用户" object作为编辑或创建用户的参数。现有用户传递给onClick罚款,但在新用户的空行上输入的信息始终具有NULL属性。但是,检查对象是否为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:
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
}
从MainWindow打开UsersWindow:
UsersViewModel Usersvm = new UsersViewModel();
Usersvm.Users = new ObservableCollection<UserViewModel>();
Usersvm.Users.Add(new UserViewModel() { FirstName = "John", LastName = "Doe", EMail = "JohnDoe@yahoo.com", 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 :(得分:0)
颠倒你正在做的事情的顺序。首先检查以确定obj是否为null。如果(且仅当) not null ,则将其转换(强制转换)为associatedViewModel。然后检查associatedViewModel是否为null。然后,如果(并且仅当)associatedViewModel not null ,您可以使用associatedViewModel.LastName。如果其中任何一个为空,则发出错误。
假设存在不应该为null的内容,请将代码减少到重新创建问题所需的最小值。
答案 1 :(得分:0)
这里的答案是DataGrid始终将原始值发送到按钮单击。将用户引导到可以通过绑定的TextBox编辑单个对象的新页面解决了这个问题。