This is a migrated thread and some comments may be shown as answers.

Rad Grid View - Selected Item Binding Two Way - MVVM

3 Answers 528 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Indika
Top achievements
Rank 1
Indika asked on 19 Sep 2010, 03:23 PM
Hello,
 I am working on wpf application with MVVM pattern. I have telerik grid containg categories of business objects ( categoryid, category number, category name). I allow user to inline gridview editing. I have managed to update, delete categories as i expected. When user add new category, user will enter category name and will save the record to database. Gridview selected item is binding with CurrentCateogry property in viewmodel and every time selection changes it will update the currenty category in the viewmodel. After user updated the record, corresponding category will save to database and generate new categoryid and category number and passes to the UI. Above all, corresponding selected item will not updating with new values though it has updated the current category property in viewmodel.

I have attached code samples as follows.

Category.cs
==========

using

 

 

System;

 

using

 

 

System.Collections.Generic;

 

using

 

 

System.Linq;

 

using

 

 

System.Text;

 

using

 

 

System.Data;

 

using

 

 

System.IO;

 

using

 

 

System.ComponentModel;

 

using

 

 

System.Data.SqlClient;

 

namespace

 

 

RadGridSelectedItemBindingTwoWay

 

{

 

 

 

public class Category : INotifyPropertyChanged

 

{

 

 

 

 

 

 

private Int32 _CategoryId;

 

 

 

private string _CategoryNumber;

 

 

 

private string _CategoryName;

 

 

 

 

 

 

public Category()

 

{

 

 

this.CategoryId = -1;

 

 

 

this.CategoryNumber = String.Empty;

 

 

 

this.CategoryName = String.Empty;

 

}

 

 

 


public
Category(Int32 CategoryId, string CategoryNumber, string CategoryName)

 

{

 

 

this.CategoryId = CategoryId;

 

 

 

this.CategoryNumber = CategoryNumber;

 

 

 

this.CategoryName = CategoryName;

 

 

}

 

 


public
Int32 CategoryId

 

{

 

 

get

 

{

 

 

return _CategoryId;

 

}

 

 

set

 

{

_CategoryId =

 

value;

 

OnPropertyChanged(

 

"CategoryId");

 

}

}

 

 

public string CategoryNumber

 

{

 

 

get

 

{

 

 

return _CategoryNumber;

 

}

 

 

set

 

{

_CategoryNumber =

 

value;

 

OnPropertyChanged(

 

"CategoryNumber");

 

}

}

 

 


public
string CategoryName

 

{

 

 

get

 

{

 

 

return _CategoryName;

 

}

 

 

set

 

{

_CategoryName =

 

value;

 

OnPropertyChanged(

 

"CategoryName");

 

}

}

 

 

 


public
override string ToString()

 

{

 

 

string CategoryString = String.Empty;

 

CategoryString =

 

this.CategoryName;

 

 

 

 

return CategoryString;

 

}

 

 


public
event PropertyChangedEventHandler PropertyChanged;

 

 

 

private void OnPropertyChanged(string propertyName)

 

{

 

 

if (this.PropertyChanged != null)

 

{

 

 

this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

 

}

}

 

}

}


MainWindow.xaml
=============

<

 

 

Window x:Class="RadGridSelectedItemBindingTwoWay.MainWindow"

 

 

 

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

 

 

 

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

 

 

 

xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"

 

 

 

xmlns:telerikGrid="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.GridView"

 

 

 

xmlns:nav="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.Navigation"

 

 

 

xmlns:RadBind="clr-namespace:RadGridSelectedItemBindingTwoWay"

 

 

 

Title="RadGridView - Selected Item Binding Two Way - MVVM" Height="350" Width="525">

 

 

 

 

<Grid>

 

 

 

 

<StackPanel Grid.Row="0" Grid.Column="0" Margin="10,10" >

 

 

 

 

<nav:RadTabControl>

 

 

 

 

<nav:RadTabItem Header="Category">

 

 

 

 

<Grid>

 

 

 

 

<Grid.RowDefinitions>

 

 

 

 

<RowDefinition Height="50*"/>

 

 

 

 

<RowDefinition Height="*"/>

 

 

 

 

<RowDefinition Height="40*"/>

 

 

 

 

</Grid.RowDefinitions>

 

 

 

 

<telerik:RadDataPager Grid.Row="0" PageSize="20" Source="{Binding Items, ElementName=CategoryRadGridView}"

 

 

 

IsTotalItemCountFixed="False" DisplayMode="FirstLastPreviousNextNumeric, Text"

 

 

 

/>

 

 

 

 

<telerikGrid:RadGridView Grid.Row="1" x:Name="CategoryRadGridView" GridLinesVisibility="Horizontal"

 

 

 

AutoGenerateColumns="False" SelectionMode="Single"

 

 

 

RowIndicatorVisibility="Hidden" IsReadOnly="False"

 

 

 

CanUserFreezeColumns="False" ScrollViewer.HorizontalScrollBarVisibility="Hidden"

 

 

 

ShowGroupPanel="False"

 

 

 

ItemsSource="{Binding Categories}"

 

 

 

ActionOnLostFocus="None"

 

 

 

SelectedItem="{Binding Path=CurrentCategory, UpdateSourceTrigger=Explicit,Mode=TwoWay}"

 

 

 

 

KeyboardNavigation.AcceptsReturn="True"

 

 

 

>

 

 

 

 

<telerikGrid:RadGridView.Columns>

 

 

 

 

<telerikGrid:GridViewDataColumn DataMemberBinding="{Binding CategoryId, Mode=TwoWay}" Header="Category Id" IsReadOnly="True" IsVisible="True" />

 

 

 

 

<telerikGrid:GridViewDataColumn DataMemberBinding="{Binding CategoryNumber, Mode=TwoWay}" Header="Category Number" Width="300*" IsReadOnly="True"/>

 

 

 

 

<telerikGrid:GridViewDataColumn DataMemberBinding="{Binding CategoryName, Mode=TwoWay}" Header="Category Name" IsVisible="True" />

 

 

 

 

 

<telerikGrid:GridViewDataColumn >

 

 

 

 

<telerikGrid:GridViewColumn.CellTemplate>

 

 

 

 

<DataTemplate>

 

 

 

 

<telerik:RadButton x:Name="Category_SaveRow" HorizontalAlignment="Stretch"

 

 

 

ToolTip="Update" Content="Update"

 

 

 

Command="{Binding Path=CategorySaveCommand}"

 

 

 

Loaded="Category_SaveRow_Loaded"

 

 

 

Click="Category_SaveRow_Click">

 

 

 

 

</telerik:RadButton>

 

 

 

 

</DataTemplate>

 

 

 

 

</telerikGrid:GridViewColumn.CellTemplate>

 

 

 

 

</telerikGrid:GridViewDataColumn>

 

 

 

 

 

<telerikGrid:GridViewDataColumn >

 

 

 

 

<telerikGrid:GridViewColumn.CellTemplate>

 

 

 

 

<DataTemplate>

 

 

 

 

<telerik:RadButton x:Name="Category_RemoveRow" HorizontalAlignment="Stretch"

 

 

 

ToolTip="Delete" Content="Delete"

 

 

 

Command="{Binding Path=CategoryDeleteCommand}"

 

 

 

Loaded="Category_RemoveRow_Loaded"

 

 

 

Click="Category_RemoveRow_Click"

 

 

 

>

 

 

 

 

</telerik:RadButton>

 

 

 

 

</DataTemplate>

 

 

 

 

</telerikGrid:GridViewColumn.CellTemplate>

 

 

 

 

</telerikGrid:GridViewDataColumn>

 

 

 

 

</telerikGrid:RadGridView.Columns>

 

 

 

 

</telerikGrid:RadGridView>

 

 

 

 

<StackPanel Grid.Row="2" Orientation="Horizontal" Margin="5">

 

 

 

 

<telerik:RadButton Grid.Row="2" Content="Add Category" Width="100" Margin="5,5"

 

 

 

Command="telerikGrid:RadGridViewCommands.BeginInsert" CommandTarget="{Binding ElementName=CategoryRadGridView}"/>

 

 

 

 

<telerik:RadButton Grid.Row="2" Content="Cancel" Width="100" Margin="5,5"

 

 

 

Command="telerikGrid:RadGridViewCommands.CancelRowEdit" CommandTarget="{Binding ElementName=CategoryRadGridView}"/>

 

 

 

 

</StackPanel>

 

 

 

 

</Grid>

 

 

 

 

 

</nav:RadTabItem>

 

 

 

 

 

</nav:RadTabControl>

 

 

 

 

</StackPanel>

 

 

 

 

</Grid>

 

</

 

 

Window>

 


MainWindowCS
-------------------

using

 

 

System.Windows;

 

using

 

 

System.Windows.Controls;

 

using

 

 

Telerik.Windows.Controls;

 

namespace

 

 

RadGridSelectedItemBindingTwoWay

 

{

 

 


public
partial class MainWindow : Window

 

{

 

 

MyViewModel _MyViewModel;

 

 

 

public MainWindow()

 

{

InitializeComponent();

_MyViewModel =

 

new MyViewModel();

 

 

 

this.DataContext = _MyViewModel;

 

}

 

 

private void Category_SaveRow_Loaded(object sender, RoutedEventArgs e)

 

{

 

 

var button = (Button)sender;

 

button.Command = _MyViewModel.CategorySaveCommand;

}

 

 

private void Category_SaveRow_Click(object sender, RoutedEventArgs e)

 

{

 

 

// TODO : Explicitly set current category of the view model

 

_MyViewModel.CurrentCategory = (

 

Category)((RadButton)sender).DataContext;

 

 

 

this.CategoryRadGridView.CommitEdit();

 

}

 

 


private
void Category_RemoveRow_Loaded(object sender, RoutedEventArgs e)

 

{

 

 

var button = (Button)sender;

 

button.Command = _MyViewModel.CategoryDeleteCommand;

}

 

 

private void Category_RemoveRow_Click(object sender, RoutedEventArgs e)

 

{

 


 

_MyViewModel.CurrentCategory = (

 

Category)((RadButton)sender).DataContext;

 

}

}

}


MyViewModel :
------------------

using

 

 

System;

 

using

 

 

System.Collections.ObjectModel;

 

using

 

 

System.ComponentModel;

 

using

 

 

System.Windows.Input;

 

using

 

 

RadGridSelectedItemBindingTwoWay.Model;

 

 

namespace

 

 

RadGridSelectedItemBindingTwoWay

 

{

 

 

public class MyViewModel : INotifyPropertyChanged

 

{

 

 

private ObservableCollection<Category> _Categories; // trigger category updates

 

 

 

private DelegateCommand _CategorySaveCommand; // Handle category save as delegate command

 

 

 

private DelegateCommand _CategoryDeleteCommand;// Handle cateogry delete as delegate command

 

 

 

 

private Category _CurrentCategory;

 

 

 

 

public MyViewModel()

 

{

 

 

this.Categories = GetComponentCategories();

 

 

 

// Initialize the delegate commands

 

_CategorySaveCommand =

 

new DelegateCommand(CategorySave);

 

_CategoryDeleteCommand =

 

new DelegateCommand(CategoryDelete);

 

}

 

 

 

 

 

public ObservableCollection<Category> Categories

 

{

 

 

get

 

{

 

 

return _Categories;

 

}

 

 

set

 

{

_Categories =

 

value;

 

 

 

this.OnPropertyChanged("Categories");

 

}

}

 

 

public ICommand CategorySaveCommand

 

{

 

 

get

 

{

 

 

if (_CategorySaveCommand == null)

 

{

_CategorySaveCommand =

 

new DelegateCommand(CategorySave);

 

}

 

 

return this._CategorySaveCommand;

 

}

}

 

 

public ICommand CategoryDeleteCommand

 

{

 

 

get

 

{

 

 

if (_CategoryDeleteCommand == null)

 

{

_CategoryDeleteCommand =

 

new DelegateCommand(CategoryDelete);

 

}

 

 

return this._CategoryDeleteCommand;

 

}

}

 

 

public Category CurrentCategory

 

{

 

 

get

 

{

 

 

return this._CurrentCategory;

 

}

 

 

set

 

{

 

 

this._CurrentCategory = value;

 

 

 

this.OnPropertyChanged("CurrentCategory");

 

}

}

 

 

 

 

private ObservableCollection<Category> GetComponentCategories()

 

{

 

 

ObservableCollection<Category> categoryOC = new ObservableCollection<Category>();

 

categoryOC.Add(

 

new Category(1, "000001", "Category1"));

 

categoryOC.Add(

 

new Category(2, "000002", "Category2"));

 

categoryOC.Add(

 

new Category(3, "000003", "Category3"));

 

 

 

 

return categoryOC;

 

}

 

 

 

 

public void CategorySave()

 

{

 

 

// Save to database and generate category id and category number and will return to the UI layer

 

 

 

Category SavedCategory = SaveCategoryToDatabaseAndReturnSavedCategory(this.CurrentCategory);

 

 

 

this.CurrentCategory = SavedCategory; // I am expecting to see save category id and catgory number as selected

 

 

 

// item is binding with current category property but not updated the UI with new values

 

 

}

 

 

private void CategoryDelete()

 

{

 

 

this.Categories.Remove(this.CurrentCategory);

 

}

 

 

private Category SaveCategoryToDatabaseAndReturnSavedCategory(Category toSaveCategory)

 

{

 

 

// Temp method to category to database and generate sequential new category id and category number

 

 

 

Category newCategory = new Category();

 

 

 

Random random = new Random();

 

newCategory.CategoryId = random.Next(100);

newCategory.CategoryNumber = newCategory.CategoryId.ToString();

newCategory.CategoryName = toSaveCategory.CategoryName;

 

 

return newCategory;

 

}

#region

 

 

INotifyPropertyChanged Members

 

 

 

 

public event PropertyChangedEventHandler PropertyChanged;

 

 

 

//protected virtual void OnPropertyChanged(string propertyName)

 

 

 

//{

 

 

 

// if (null != this.PropertyChanged)

 

 

 

// {

 

 

 

// this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

 

 

 

// }

 

 

 

//}

 

 

 

//protected virtual void NotifyPropertyChanged(string propertyname)

 

 

 

//{

 

 

 

// if (PropertyChanged != null)

 

 

 

// {

 

 

 

// PropertyChanged(this, new PropertyChangedEventArgs(propertyname));

 

 

 

// }

 

 

 

//}

 

 

 

protected virtual void OnPropertyChanged(PropertyChangedEventArgs args)

 

{

 

 

PropertyChangedEventHandler handler = this.PropertyChanged;

 

 

 

if (handler != null)

 

{

handler(

 

this, args);

 

}

}

 

 

private void OnPropertyChanged(string propertyName)

 

{

 

 

this.OnPropertyChanged(new PropertyChangedEventArgs(propertyName));

 

}

#endregion

}

}


Command
-------------

public

 

 

class DelegateCommand : ICommand

 

{

 

 

private Action _executeMethod;

 

 

 

public DelegateCommand(Action executeMethod)

 

{

_executeMethod = executeMethod;

}

 

 

public bool CanExecute(object parameter)

 

{

 

 

return true;

 

}

 

 

public event EventHandler CanExecuteChanged;

 

 

 

public void Execute(object parameter)

 

{

_executeMethod.Invoke();

}

}


Thanking You..

3 Answers, 1 is accepted

Sort by
0
Milan
Telerik team
answered on 20 Sep 2010, 11:34 AM
Hi Indika,

As far as I can see you have set UpdateSourceTrigger=Explicit which means that SelectedItem will not be updated automatically when CurrentCategory is changed. SelectedItem should start updating If you remove the setter for UpdateSourceTrigger.


Regards,
Milan
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Laura
Top achievements
Rank 1
answered on 01 Sep 2011, 05:35 AM
I have the same issue, and I'm not setting the UpdateSourceTrigger on the binding. I'm using 2011.1.419.35.

LauraH
0
Maya
Telerik team
answered on 03 Sep 2011, 03:04 PM
Hi Laura,

Will it be possible to share a bit more details about your settings and the exact scenario you want to accomplish ? Can you reproduce the same behavior with our current official release - Q2 2011 ? 
 

Kind regards,
Maya
the Telerik team

Thank you for being the most amazing .NET community! Your unfailing support is what helps us charge forward! We'd appreciate your vote for Telerik in this year's DevProConnections Awards. We are competing in mind-blowing 20 categories and every vote counts! VOTE for Telerik NOW >>

Tags
GridView
Asked by
Indika
Top achievements
Rank 1
Answers by
Milan
Telerik team
Laura
Top achievements
Rank 1
Maya
Telerik team
Share this question
or