I have a view with a button and a dataGrid. The XAML file is this:
<Window x:Class="MusicaDB.Views.PrincipalView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
Title="Principal" mc:Ignorable="d" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" d:DesignHeight="627" d:DesignWidth="1176" SizeToContent="WidthAndHeight">
<Window.Resources>
<DataTemplate x:Key="BlueHeader">
<StackPanel Orientation="Horizontal" Margin="-5,-5,-5,-5" Width="120">
<StackPanel.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF223B84" Offset="1"/>
<GradientStop Color="#FF57A0F4" Offset="0.5"/>
<GradientStop Color="#FF4B94EC" Offset="0.5"/>
</LinearGradientBrush>
</StackPanel.Background>
<TextBlock Margin="10,10,10,10" Text="{Binding}" VerticalAlignment="Center" Foreground="White"/>
</StackPanel>
</DataTemplate>
</Window.Resources>
<Button Content="Search"
Height="23"
HorizontalAlignment="Left"
Margin="12,165,0,0"
Name="btnPersonSearch"
VerticalAlignment="Top"
Width="48">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:InvokeCommandAction
Command="{Binding PersonSearch}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
<Grid Height="558" Width="1099">
<DataGrid
Height="164"
HorizontalAlignment="Left"
Margin="339,24,0,0"
Name="dgdAutores"
VerticalAlignment="Top"
Width="540"
IsTextSearchEnabled="True"
CanUserAddRows="True"
CanUserDeleteRows="True"
ItemsSource="{Binding DgdPersons}">
<DataGrid.Columns>
<DataGridTextColumn Header="IDPerson" Binding="{Binding IDPerson}"></DataGridTextColumn>
<DataGridTextColumn Header="Name" Binding="{Binding Name}"></DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
In my ViewModel.cs I have two properties, one for the binding and other for the command.
`
private ObservableCollection<Persons> _dgdPersons;
public ICommand _personsSearch { get; set; }
public ObservableCollection<Persons> DgdPersons
{
get { return _dgdPersons; }
set
{
_dgdPersons = value;
base.RaisePropertyChangedEvent("DgdPersons");
}
}
public ICommand PersonsSearch
{
get{return _personsSearch;}
}`
This is the code that I use to search persons, in which I update Persons:
using System;
using System.Windows.Input;
using PersonsDB.ViewModel;
using System.Collections.ObjectModel;
using PersonsDB.DBModels;
using System.Windows.Controls;
namespace MusicaDB.Commands
{
public class AutoresBuscarCommand : ICommand
{
private ViewModelMain _ViewModel;
public PersonsSearchCommand(ViewModelMain viewModel)
{
_ViewModel = viewModel;
}
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(Object parameter)
{
_ViewModel.DgdPersons = _ViewModel.DBManager.getPersons("Parameters of serach");
}
}
}
NOTE: DBManager is a class that let me access to the database. This class internaly use EF 4.1 and the method getPersons returns context.Persons.Local.
This Command class inherit from a base class:
using System.ComponentModel;
namespace PersonsDB.ViewModel
{
public abstract class ViewModelBase : INotifyPropertyChanging, INotifyPropertyChanged
{
public event PropertyChangingEventHandler PropertyChanging;
public event PropertyChangedEventHandler PropertyChanged;
public virtual bool IgnorePropertyChangeEvents { get; set; }
public virtual void RaisePropertyChangedEvent(string propertyName)
{
// Exit if changes ignored
if (IgnorePropertyChangeEvents) return;
// Exit if no subscribers
if (PropertyChanged == null) return;
// Raise event
var e = new PropertyChangedEventArgs(propertyName);
PropertyChanged(this, e);
}
public virtual void RaisePropertyChangingEvent(string propertyName)
{
// Exit if changes ignored
if (IgnorePropertyChangeEvents) return;
// Exit if no subscribers
if (PropertyChanging == null) return;
// Raise event
var e = new PropertyChangingEventArgs(propertyName);
PropertyChanging(this, e);
}
}
}
Well, for not to put a lot of code, I have other class, PersonsSearchCommand that execute the command. This command, also, use other class to request data from the DataBase. This class use EF 4.1 and return context.Persons.Local. This return is what I set the ObservableCollection Persons of the ModelView.
This works, at least and the first time I click the button. The rest of the times the dataGrid does not receive data, does not binding the new results.
I try, in my command class, first, clear the ObservableCollection persons with the clear() method, create a temporal ObservableCollection to receive the return Persons.Local and use a foreach with this temporal ObservableCollection to add its elements to the ObservableCollection Persons to detect new changes, but this doesn`t work. I know that this a bad solution, because if the local has a lot of elements, it could be very slow, but it was to see if I get to update the dataGrid, but not.
Why is it only works the first time?
Thanks.
Daimroc.
EDIT: I have added new code.
EDIT 2: Solved.
Well, finally I found the error. The problem is not of the binding, it’s my fault, because I have converted the code from CodeBehind to the MVVM and I am modifying the ItemsSorce in the code-behind too.
I do not realized that the button to clear the search criteria changed the dataGrid from the code-behind and then the itemsSource changed in a way not anticipated.
I have now created a new command for the button clean and works as it should be.
Thank you very much for your help. Daimroc.
I haven’t read all of your code, but off the top of my head, why are you using an interaction trigger rather than just using the
Commandproperty of the button? That might be the first thing you try.