0

I am new to WPF and i need a quick help please.

  • I have a datagrid that is bound with Observable collection
  • the selected item of datagrid is bound to a property of sameobject as of observable collection
  • I have textboxes bound to the selected item of datagrid
  • I have a button "New" when pressed will make all the textboxes empty

What I want to achieve is that if the datagrid selected item is not null then update the record and if it is null then insert a new record. I want to achieve this using commands

Below here is the Model. The Database Management class implements 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;
    }
}

Here is the VIEW MODEL

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
}

and Here is my View

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

Please help me how i can achieve this. I am not allowed to insert image as i am new user of stackoverflow. Thanks in advance

mdeous
  • 17,513
  • 7
  • 56
  • 60
Bilal Aslam
  • 3
  • 1
  • 2

1 Answers1

1

1) create a new button in XAML

2) create a new command in UserVM class(call it UpdateOrAddNew command) and associate it with the button using "Command" property.

See this for more information: How to bind WPF button to a command in ViewModelBase?

3) In your UpdateOrAddNew command handler, check if SelectedUser is null(then create new user) or if it's not null, update existing one.

To take car of the TextBox issue, you need to create a wrapper that holds always information.

Add this to your UserVM:

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

now you need to modify your TextBoxes to bind against UserRecord, instead of SelectedUser.

and modify your SelectedUser:

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

        UserRecord = selecteduser;
    }
}
Community
  • 1
  • 1
Erti-Chris Eelmaa
  • 25,338
  • 6
  • 61
  • 78
  • Thank you for your quick response. I already have the Command and action is updateUser. i can access the SelectedUser property if datagrid item is selected. But if this is null how i can get the data from textboxes to my VIEWMODEL? – Bilal Aslam Dec 23 '13 at 11:42
  • I edited the post. Does this take care of your problem? – Erti-Chris Eelmaa Dec 23 '13 at 11:57
  • Hey i have another question. Change in UserRecord property does not appear unless the focus is out from textbox. How i can fix this? – Bilal Aslam Dec 23 '13 at 12:32