【问题标题】:WPF Databinding with element and add new record MVVMWPF 数据绑定与元素并添加新记录 MVVM
【发布时间】:2013-12-23 11:27:30
【问题描述】:

我是 WPF 新手,需要快速帮助。

  • 我有一个与 Observable 集合绑定的数据网格
  • datagrid 的选定项绑定到与 observable 集合相同的对象的属性
  • 我有文本框绑定到数据网格的选定项
  • 我有一个“新建”按钮,按下时所有文本框都为空

我想要实现的是,如果数据网格所选项目不为空,则更新记录,如果为空,则插入新记录。我想使用命令来实现这一点

下面是模型。数据库管理类实现 INotifyPropertyChanged

class User:DatabaseManagement
{
    #region VARIABLES
    private int userID;
    private string firstName;
    private string lastName;
    private string email;

    DataTable dt;
    #endregion

    #region PROPERTIES
    public int UserID
    {
        get { return userID; }
        set { userID = value;
        onPropertyChanged("UserID");
        }            
    }
    public string FirstName
    {
        get { return firstName; }
        set { firstName = value;
        onPropertyChanged("FirstName");
        }
    }
    public string LastName
    {
        get { return lastName; }
        set { lastName = value;
        onPropertyChanged("LastName");
        }
    }
    public string Email
    {
        get { return email; }
        set { email = value;
        onPropertyChanged("Email");
        }
    }

    #endregion

    public User()
    {

    }
    public User(int userid, string firstname, string lastname, string email)
    {
        UserID = userid;
        FirstName = firstname;
        LastName = lastname;
        Email = email;
    }
}

这是视图模型

class UserVM : ViewModelBase
{
    #region VARIABLES
    private ObservableCollection<User> user_list = new ObservableCollection<User>();
    private User selecteduser;
    private DataTable dtusers;
    private User obj_user;

    private ICommand cmdupdateuser;
    private ICommand cmdnewuser;
    #endregion

    #region PROPERTIES
    public ObservableCollection<User> UserList
    {
        get { return user_list; }
        set {
            user_list = value;
            onPropertyChanged("UserList");
        }
    }
    public User SelectedUser
    {
        get { return selecteduser; }
        set
        {
            selecteduser = value;
            onPropertyChanged("SelectedUser");
        }
    }
    public ICommand UpdateUserCommand
    {
        get { return cmdupdateuser; }
        set
        {
            cmdupdateuser = value;
            onPropertyChanged("UpdateUserCommand");
        }
    }
    public ICommand NewUserCommand
    {
        get { return cmdnewuser; }
        set
        {
            cmdnewuser = value;
            onPropertyChanged("NewUserCommand");
        }
    }
    #endregion

    #region CONSTRUCTOR
    public UserVM()
    {
        getAllUsers();
        UpdateUserCommand = new RelayCommand(new Action<object>(updateUser));
    }
    #endregion

    #region FUNCTIONS
    private void getAllUsers()
    {
        obj_user = new User();
        dtusers = obj_user.getAllUsers();

        foreach (DataRow row in dtusers.Rows)
        {
            UserList.Add(
                new User(
                    Convert.ToInt16(row["UserID"]),
                    row["FirstName"].ToString(),
                    row["LastName"].ToString(),
                    row["Email"].ToString()
                )
            );
        }
    }

    public void updateUser(object parameters)
    {

        User selecteduser = SelectedUser;
        int rows = obj_user.updateUser(selecteduser);
        if (rows > 0)
        {
            UserList.Clear();
            getAllUsers();
        }
    }
    #endregion
}

这是我的观点

<Page x:Class="IMS.View.PageUser"
  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:user="clr-namespace:IMS.ViewModel"
  mc:Ignorable="d" 
  x:Name="pageuser"
  d:DesignHeight="477" d:DesignWidth="695"
Title="PageUser" Loaded="Page_Loaded">
<Page.Resources>

    <user:UserVM x:Key="UserVM"></user:UserVM>
</Page.Resources>


<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition MinWidth="200" />
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition MinWidth="500" />
    </Grid.ColumnDefinitions>

    <DataGrid AutoGenerateColumns="False" Grid.Column="0" Height="Auto" HorizontalAlignment="Stretch" Margin="0" Name="userdatagrid" VerticalAlignment="Stretch" Width="Auto" 
              DataContext="{Binding Source={StaticResource UserVM}}"
              ItemsSource="{Binding  Path=UserList}" SelectionChanged="dataGrid1_SelectionChanged"
              SelectedItem="{Binding SelectedUser}" CanUserAddRows="False" CanUserDeleteRows="False">
        <DataGrid.Columns>
            <DataGridTextColumn Header="User ID" Binding="{Binding UserID}" />
            <DataGridTextColumn Header="Name" Binding="{Binding FirstName}" />
        </DataGrid.Columns>
    </DataGrid>

    <GridSplitter Grid.Column="1" Height="Auto" HorizontalAlignment="Right" Margin="0" Name="gridSplitter1" VerticalAlignment="Stretch" Width="10" ResizeDirection="Columns" ResizeBehavior="PreviousAndNext" Background="#FFEB3333" />

    <DockPanel Grid.Column="2" Height="Auto" Name="dockPanel1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Width="Auto">
        <Menu Grid.Column="2" Height="25" HorizontalAlignment="Stretch" Margin="0" Name="menu1" VerticalAlignment="Top" Width="Auto" DockPanel.Dock="Top"  DataContext="{Binding Source={StaticResource UserVM}}">
            <MenuItem Header="New" Click="MI_New_Click" />
            <MenuItem Header="Save" Command="{Binding UpdateUserCommand}" />
        </Menu>
        <Grid Height="Auto" Name="grid1" Width="Auto" DockPanel.Dock="Top" DataContext="{Binding Source={StaticResource UserVM}}">
            <Grid.RowDefinitions>
                <RowDefinition Height="38*" />
                <RowDefinition Height="44*" />
                <RowDefinition Height="45*" />
                <RowDefinition Height="46*" />
                <RowDefinition Height="43*" />
                <RowDefinition Height="236*" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="142*" />
                <ColumnDefinition Width="358*" />
            </Grid.ColumnDefinitions>
            <Label Content="First Name:" Height="28" HorizontalAlignment="Left" Margin="6,7,0,0" Name="lblfirstname" VerticalAlignment="Top" />
            <Label Content="Last Name:" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="6,6,0,0" Name="lbllastname" VerticalAlignment="Top" />
            <Label Content="Email:" Grid.Row="2" Height="28" HorizontalAlignment="Left" Margin="6,11,0,0" Name="lblemail" VerticalAlignment="Top" />
            <TextBox Grid.Column="1" Height="23" HorizontalAlignment="Left" Margin="8,7,0,0" Name="txtfirstname" VerticalAlignment="Top" Width="120" 
                     Text="{Binding Path=SelectedUser.FirstName}" />
            <TextBox Grid.Column="1" Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="8,11,0,0" Name="txtlastname" VerticalAlignment="Top" Width="120" 
                     Text="{Binding ElementName=userdatagrid, Path=SelectedItem.LastName}"/>
            <TextBox Grid.Column="1" Grid.Row="2" Height="23" HorizontalAlignment="Left" Margin="8,16,0,0" Name="txtemail" VerticalAlignment="Top" Width="120" 
                     Text="{Binding ElementName=userdatagrid, Path=SelectedItem.Email}"/>
        </Grid>
    </DockPanel>
</Grid>
</Page>

请帮助我如何实现这一目标。我是 stackoverflow 的新用户,不允许插入图像。提前致谢

【问题讨论】:

    标签: wpf data-binding


    【解决方案1】:

    1) 在 XAML 中创建一个新按钮

    2) 在 UserVM 类中创建一个新命令(称为 UpdateOrAddNew 命令)并使用“Command”属性将其与按钮相关联。

    更多信息请参见:How to bind WPF button to a command in ViewModelBase?

    3) 在您的 UpdateOrAddNew 命令处理程序中,检查 SelectedUser 是否为 null(然后创建新用户),或者如果它不为 null,则更新现有用户。

    要解决 TextBox 问题,您需要创建一个始终保存信息的包装器。

    将此添加到您的 UserVM:

    public User UserRecord
    {
        get
        {
           if(userRecord == null)
             return userRecord = new User();
        }
        set
        {
            userRecord = value;
            onPropertyChanged("UserRecord");
        }
    }
    

    现在你需要修改你的 TextBoxes 来绑定 UserRecord,而不是 SelectedUser。

    并修改您的 SelectedUser:

    public User SelectedUser
    {
        get { return selecteduser; }
        set
        {
            selecteduser = value;
            onPropertyChanged("SelectedUser");
    
            UserRecord = selecteduser;
        }
    }
    

    【讨论】:

    • 感谢您的快速回复。我已经有了命令,操作是 updateUser。如果选择了数据网格项,我可以访问 SelectedUser 属性。但是,如果这是 null 我如何将数据从文本框中获取到我的 VIEWMODEL?
    • 我编辑了这篇文章。这能解决您的问题吗?
    • 嘿,我还有一个问题。除非焦点不在文本框中,否则不会出现 UserRecord 属性的更改。我该如何解决这个问题?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-24
    • 1970-01-01
    • 2015-09-20
    • 1970-01-01
    • 1970-01-01
    • 2019-06-23
    • 1970-01-01
    相关资源
    最近更新 更多