How to delete selected row from a datagridwith context menu in Silverlight?
I need to be able to delete a selected row from a datagrid with "Delete” context menu item. I have hard time finding the path to the selected row. I am wondering if someone can look at the code below and let me know what will be the appropriate to do within my code. Thank you in advance.
XAML:
<UserControl.DataContext>
<local:MainPage_ViewModel/>
</UserControl.DataContext>
<StackPanel Orientation="Horizontal">
<data:DataGrid ItemsSource="{Binding Coordinates}" AutoGenerateColumns="False" Margin="10">
<!-- ContextMenu -->
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu x:Name="Menu" >
<toolkit:MenuItem x:Name="Edit" />
<toolkit:MenuItem x:Name="Delete" Tag="{Binding}" Click="Button_Click" />
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
<data:DataGrid.Columns>
<data:DataGridTextColumn Header="X Position" Width="100" Binding="{Binding X}"/>
<data:DataGridTextColumn Header="Y Position" Width="100" Binding="{Binding Y}"/>
<data:DataGridTemplateColumn Header="Delete Item" Width="100">
<data:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Content="Delete" Tag="{Binding}" Click="Button_Click"/>
</DataTemplate>
</data:DataGridTemplateColumn.CellTemplate>
</data:DataGridTemplateColumn>
</data:DataGrid.Columns>
</data:DataGrid>
Code behind:
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
this.viewModel = this.DataContext as MainPage_ViewModel;
}
private MainPage_ViewModel viewModel;
private void Button_Click(object sender, RoutedEventArgs e)
{
viewModel.DeleteCoordinate((sender as Button).Tag as Coordinate_DataViewModel);
}
}
ViewModel:
public class MainPage_ViewModel : INotifyPropertyChanged
{
public MainPage_ViewModel()
{
coordinates.Add(new Coordinate_DataViewModel(new Coordinate_Model() { X = 1, Y = 2 }));
coordinates.Add(new Coordinate_DataViewModel(new Coordinate_Model() { X = 2, Y = 4 }));
coordinates.Add(new Coordinate_DataViewModel(new Coordinate_Model() { X = 3, Y = 6 }));
coordinates.Add(new Coordinate_DataViewModel(new Coordinate_Model() { X = 4, Y = 8 }));
coordinates.Add(new Coordinate_DataViewModel(new Coordinate_Model() { X = 5, Y = 10 }));
coordinates.Add(new Coordinate_DataViewModel(new Coordinate_Model() { X = 6, Y = 12 }));
}
public ObservableCollection<Coordinate_DataViewModel> Coordinates
{
get { return coordinates; }
set
{
if (coordinates != value)
{
coordinates = value;
OnPropertyChanged("Coordinates");
}
}
}
private ObservableCollection<Coordinate_DataViewModel> coordinates = new ObservableCollection<Coordinate_DataViewModel>();
public event PropertyChangedEventHandler PropertyChanged;
pu开发者_如何学Cblic void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public void DeleteCoordinate(Coordinate_DataViewModel dvmToDelete)
{
coordinates.Remove(dvmToDelete);
}
public void UpdateCoordinate(Coordinate_DataViewModel dvmToDelete)
{
}
}
//Model
public class Coordinate_Model
{
public double X;
public double Y;
}
//DataViewModel
public class Coordinate_DataViewModel
{
public Coordinate_DataViewModel(Coordinate_Model model)
{
this.underlyingModel = model;
}
private Coordinate_Model underlyingModel;
public double X
{
get { return underlyingModel.X; }
set { underlyingModel.X = value; }
}
public double Y
{
get { return underlyingModel.Y; }
set { underlyingModel.Y = value; }
} public string XYCoordinate
{
get { return "(" + X + "," + Y + ")"; }
}
}
Update your datagrid to bind to a selected item on your viewModel. Update your datagrid as follows:
<data:DataGrid ItemsSource="{Binding Coordinates}" AutoGenerateColumns="False" Margin="10" SelectedItem="{Binding SelectedItem, Mode=TwoWay}">
On your view model, add the following property:
public Coordinate_DataViewModel SelectedItem
{
get { return selectedItem; }
set { selectedItem = value; }
}
private Coordinate_DataViewModel selectedItem;
Then, you could add the following method to your view model:
public void DeleteSelectedItem()
{
DeleteCoordinate(this.SelectedItem);
}
Now, hook up your 'Delete' button on the context menu to the DeleteSelectedItem() and you should be good to go.
Hope this helps!
Edit for comment response: Here's an example of what you could add to implement the issue you mentioned in the comments where you don't always want to be able to delete the item. Notice i added the INotifyPropertyChanged to the setter of the SelectedItem so that the bindings of IsDeletable will be updated.
public Coordinate_DataViewModel SelectedItem
{
get { return selectedItem; }
set
{
selectedItem = value;
OnPropertyChanged("IsDeletable");
}
}
private Coordinate_DataViewModel selectedItem;
public Visibility IsDeletable
{
get
{
if (SelectedItem.Y == 2)
{
return Visibility.Collapsed;
}
return Visibility.Visible;
}
}
Bind the data grids SelectedItem to a property in your ViewModel. Use commanding to fire a method in your ViewModel when the delete button is clicked. Then remove the item from the ObservableCollection.
If you want to delete multiple items: Handling DataGrid.SelectedItems in an MVVM-friendly manner
精彩评论