WPF对象检查时不是NULL,而是属性NULL [英] WPF Object not NULL on check, but Properties NULL

查看:103
本文介绍了WPF对象检查时不是NULL,而是属性NULL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用RelayCommand构建第一个WPF程序,然后单击按钮以传递用户对象作为参数来编辑或创建用户。现有用户对onClick表示满意,但是在空白行中为新用户输入的信息始终具有NULL属性。但是,检查对象是否为NULL的测试始终表明该对象不是。对象如何不能为NULL,但在窗口中输入的内容却是?有人能发现新对象上的绑定有问题吗?

I'm building my first WPF program using a RelayCommand and button click to pass a "User" object as a parameter to edit or create a user. Existing users pass to the onClick fine, but information entered on the blank row for a new user always has NULL properties. A test to check if the object is NULL always indicates the object is not, however. How can the object be not NULL but its contents entered in the window are? Can anyone spot something wrong with the binding on the new object? Many thanks in advance!

UserViewModel类:

UserViewModel class:

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类:

UsersViewModel class:

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));
        }
    }
}

The RelayCommand:

The 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
}

从主窗口打开UsersWindow:

Opening the UsersWindow from the MainWindow:

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:

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>


推荐答案

此处的答案是DataGrid始终在发送单击按钮的原始值。将用户定向到可以通过绑定的TextBox编辑单个对象的新页面,即可解决此问题。

The answer here was that the DataGrid was always sending the original values to the button click. Directing the user to a new page where the single object can be edited via binded TextBoxes solved the problem.

这篇关于WPF对象检查时不是NULL,而是属性NULL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆