【问题标题】:WPF New DataGrid Row Parameter NULL on Button Command按钮命令上的 WPF 新 DataGrid 行参数 NULL
【发布时间】:2016-08-03 18:57:32
【问题描述】:

这里是 WPF 的新手。我正在构建的第一个应用程序使用 RelayCommand 和 DataGrid 和 ButtonCommand 来编辑或输入新用户。对于在打开的行中输入值的新用户,按下时会调用 OneditButtonCommand,但作为参数传递的 Item 始终为 null。我尝试在 XAML 中切换 Command 和 CommandParameter 的顺序,以查看是否在定义的参数之前设置了 Command,但按钮命令对象仍然为 NULL。有什么解决方案跳出来给任何人吗?非常感谢!

视图模型:

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

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

        this.Users = new ObservableCollection<UserViewModel>();

        this.Users.Add(new UserViewModel() { FirstName = "John", LastName = "Doe", EMail = "JohnDoe@yahoo.com", EndDate = new DateTime(2016,2,1), Position = "Developer", UserID = 0 });
    }

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

    private void OneditButton_Click_Command(UserViewModel obj)
    {
        //Parameter object is always NULL here!!!
    }

    public event PropertyChangedEventHandler PropertyChanged;

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

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>
        <FrameworkElement x:Name="dummyElement" Visibility="Collapsed" />
        <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>

RelayCommand 取自这里:http://www.kellydun.com/wpf-relaycommand-with-parameter/

编辑: 建议发布 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 Usersvm = new UsersViewModel();
Usersvm.Users = new ObservableCollection<UserViewModel>();
DbEntities db = new DbEntities();
var pulledUsers = db.uspGetNonAdminUsers().ToList();
foreach (var result in pulledUsers)
{
    var pulledUser = new UserViewModel
    {
        FirstName = result.FirstName,
        LastName = result.LastName,
        EMail = result.Email,
        UserID = result.UserID,
        Position = result.Position,
        EndDate = result.EndDate
    };
    Usersvm.Users.Add(pulledUser);
}
new UsersWindow(Usersvm).Show();

用户窗口:

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

【问题讨论】:

  • 阅读代码看起来应该可以工作,没有明显的问题。尝试将参数类型更改为object,看看是否得到不同的类型。
  • 谢谢@benPearce。我将私有 void OneditButton_Click_Command 上的参数类型更改为对象,现在单击按钮不会命中该函数。这是正确的改变吗?
  • 不太确定这只是收集更多信息的猜测,您可能还需要将 RelayCommand 更改为对象。
  • 这就是 d.moncada 下面的建议。进行更改后,通过测试的对象不为 NULL,强制转换的 ViewModel 通过了测试!= NULL,但从那里拉出的任何字段,如 LastName,仍然为 NULL。这是否特别说明了什么?

标签: c# wpf xaml data-binding datagrid


【解决方案1】:

你需要做几件事:

将您的属性更新为object

   public RelayCommand<object> editButton_Click_Command { get; set; }

更新您的实例以使用 object

editButton_Click_Command = new RelayCommand<object>(OneditButton_Click_Command);

然后,将您的事件处理程序更新为具有参数 object 并进行相应的转换。

private void OneditButton_Click_Command(object obj)
{
    var associatedViewModel = obj as UserViewModel;
    if (associatedViewModel != null)
    {

    }
}

【讨论】:

  • 谢谢@d.moncada。已经进行了更改,并且测试表明原始传递的 obj 和关联的 ViewModel 都不是 NULL,但是检索到的任何值(如 LastName)都是 NULL。有什么想法吗?
  • 好的,这样就解决了您的第一个问题(将空对象传递给命令)。听起来您在使用 DataBinding 和您的整体 UserViewModel 时遇到了其他问题。您将需要为您的 UserViewModel 类发布代码......但我建议您提出一个新问题,因为这个问题似乎无关(基于您的标题)
  • 再次感谢。我发布了 UserViewModel 以查看是否有任何问题以及其他问题是否更合适。
  • 有趣.. 我已经复制了你的代码,在编辑命令上放了一个断点,我看到 'John' 设置为名字。你试过闯入吗?它似乎按预期工作。
  • 是的,在函数内部设置了一个断点。在 associatedViewModel 转换之后,一个新的“string lastName = associatedViewModel.LastName;”为姓氏返回 NULL。但是,“if (associatedViewModel == null)”语句表明 associatedViewModel 不为 NULL。知道那里发生了什么吗?我还从数据库中引入了其他几个测试用户。我将更新原始问题以反映该细节。
猜你喜欢
  • 2013-10-13
  • 2017-07-25
  • 2013-04-03
  • 1970-01-01
  • 2012-11-24
  • 2019-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多