DataGrid checkall not working - c#

Hi have a Datagrid with rowCheckBoxes and an header checkbox for checking all.
The header checkbox bind a method in MainViewModel who will update the property of my model data to true. But the checkboxes are still unchecked.
<DataGrid AutoGenerateColumns="False" x:Name="grdLignes" HorizontalAlignment="Stretch" Margin="0,0,0,0"
VerticalAlignment="Stretch" CanUserAddRows="False" CanUserDeleteRows="False" Grid.ColumnSpan="2"
ItemsSource="{Binding CmLignes, UpdateSourceTrigger=PropertyChanged}">
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=hasLink, Mode=OneTime}" Value="True"/>
</MultiDataTrigger.Conditions>
<Setter Property="IsEnabled" Value="False"/>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.Header>
<CheckBox Command="{Binding RelativeSource={RelativeSource AncestorType=Window, Mode=FindAncestor}, Path=DataContext.ToggleCheckAll}" CommandParameter="{Binding IsChecked, RelativeSource={RelativeSource Self}}"/>
</DataGridTemplateColumn.Header>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox Name="rowCheck" VerticalAlignment="Center" HorizontalAlignment="Center" IsChecked="{Binding Path=hasLink, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Ref Mag" Binding="{Binding Path=refMag}" IsReadOnly="True"/>
<DataGridTextColumn Header="Ref Fourn" Binding="{Binding Path=refFourn}"/>
<DataGridTextColumn Header="Désignation" Binding="{Binding Path=design}"/>
<DataGridTextColumn Header="Quantité" Binding="{Binding Path=qte, StringFormat=N2}"/>
<DataGridTemplateColumn Header="Fournisseur">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<!--<ComboBox ItemsSource="{Binding FournList, RelativeSource={RelativeSource AncestorType=Window}}" SelectedItem="{Binding Path=fourn}"/>-->
<ComboBox ItemsSource="{Binding Path=fournList}" SelectedItem="{Binding Path=selectedFourn, UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Fourn princ" Binding="{Binding Path=fournPrinc}" IsReadOnly="True"/>
<DataGridTextColumn Header="Pièce" Binding="{Binding Path=numPiece}" IsReadOnly="True"/>
</DataGrid.Columns>
</DataGrid>
Then the MainViewModel:
public class MainViewModel : INotifyPropertyChanged
{
private ContremarqueRepository cmRepos;
private ObservableCollection<Contremarque> cmLignes;
public ObservableCollection<Contremarque> CmLignes
{
get { return cmLignes; }
set
{
cmLignes = value;
OnPropertyChanged("CmLignes");
}
}
public ICommand ToggleCheckAll { get; set; }
public MainViewModel()
{
Collection<Contremarque> cms = cmRepos.getAll(doPiece);
CmLignes = new ObservableCollection<Contremarque>(cms);
ToggleCheckAll = new Command(ActionToggleCheckAll);
}
private void ActionToggleCheckAll(object param)
{
bool isChecked = (bool)param;
if (isChecked)
{
foreach (Contremarque contremarque in CmLignes)
{
contremarque.hasLink = true;
}
}
OnPropertyChanged("CmLignes");
}
}
This is the Contremarque class:
public class Contremarque
{
public bool hasLink { get; set; }
public string refMag { get; set; }
public string refFourn { get; set; }
public string design { get; set; }
public double qte { get; set; }
public string fournPrinc { get; set; }
public List<string> fournList { get; set; }
public string selectedFourn { get; set; }
public string numPiece { get; set; }
public int dlNo;
public override string ToString()
{
string str = string.Empty;
foreach (var prop in this.GetType().GetProperties())
{
str += string.Format("{0} = {1} ", prop.Name, prop.GetValue(this, null));
}
return str;
}
}
The propertyChanged should update the state of my checkboxes isn't it?

Your class Contremarque should implement INotifyPropertyChanged and property hasLink should look like that:
public class Contremarque : INotifyPropertyChanged
{
private bool _hasLink;
public bool hasLink
{
get { return _hasLink; }
set
{
_hasLink= value;
OnPropertyChanged();
}
}
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}

Related

Databind ObservableCollection<Object> to DataGrid WPF C#

i have a xaml page in namespace Dca.KnxPanel.View with a Datagrid defined as
<DataGrid Grid.Row="2" Grid.Column="2" Name="GroupAddressDataGrid" ItemsSource="{Binding Source={x:Static viewModel:DcaAppVm._ProjectGroupAddress}}" AutoGenerateColumns="False" Margin="14,0,-14,0" Grid.RowSpan="2" >
<Border Background="GhostWhite" BorderBrush="Gainsboro" BorderThickness="1">
</Border>
<DataGrid.Columns>
<DataGridTextColumn Header="Group Address" Binding="{Binding Path=Address_Value}" Width="Auto"/>
<DataGridTextColumn Header="Description" Binding="{Binding Path=Datapoint_Name}" Width="Auto"/>
<DataGridTextColumn Header="Length" Binding="{Binding Path=Datapoint_Object_Size}" Width="Auto"/>
</DataGrid.Columns>
</DataGrid>
where the DCA_GroupAddressList and DCA_GroupAddress are defined as in the namespace Dca.KnxPanel.Model
namespace Dca.KnxPanel.Model
{
[DebuggerDisplay("{Address_Value} {Datapoint_Name} {Datapoint_Object_Size}")]
public class DCA_GroupAddress
{
public DCA_GroupAddress(GroupAddress data) {
Address_Value = data.AddressValue.ToString();
Datapoint_Name = data.Name;
if (data.ObjectSize != null)
{
Datapoint_Object_Size = data.ObjectSize.Value;
}
}
public string Address_Value { get; set; }
public string Datapoint_Name { get; set; }
public ObjectSize Datapoint_Object_Size { get; set; }
}
public class DCA_GroupAddressList : ObservableCollection<DCA_GroupAddress>
{
public static DCA_GroupAddressList dca_groupaddresslist { get; set; }
public void Add(GroupAddress item)
{
this.Add(new DCA_GroupAddress(item));
this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item));
}
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (e.Action != null)
{
base.OnCollectionChanged(e);
}
}
}
}
the problem is that the Binding data in DataGrid not works but i don't understand why...
Can you help me?
i have tried many solution and at the end this is what works:
<DataGrid Grid.Row="2" Grid.Column="2" Name="GroupAddressDataGrid" ItemsSource="{Binding _ProjectGroupAddress}" AutoGenerateColumns="False" Margin="14,0,-14,0" Grid.RowSpan="2" >
<Border Background="GhostWhite" BorderBrush="Gainsboro" BorderThickness="1">
</Border>
<DataGrid.Columns>
<DataGridTextColumn Header="Group Address" Binding="{Binding Path=Address_Value}" Width="Auto"/>
<DataGridTextColumn Header="Description" Binding="{Binding Path=Datapoint_Name}" Width="Auto"/>
<DataGridTextColumn Header="Length" Binding="{Binding Path=Datapoint_Object_Size}" Width="Auto"/>
</DataGrid.Columns>
</DataGrid>
The class DCA_GroupAddress now is:
public class DCA_GroupAddress : INotifyPropertyChanged
{
private string address_value, datapoint_name;
private ObjectSize datapoint_object_size;
public DCA_GroupAddress(GroupAddress data) {
Address_Value = data.AddressValue.ToString();
Datapoint_Name = data.Name;
if (data.ObjectSize != null)
{
Datapoint_Object_Size = data.ObjectSize.Value;
}
}
public string Address_Value {
get { return address_value; }
set {
address_value = value;
OnPropertyChanged(new PropertyChangedEventArgs("address_value"));
}
}
public string Datapoint_Name
{
get { return datapoint_name; }
set
{
datapoint_name = value;
OnPropertyChanged(new PropertyChangedEventArgs("datapoint_name"));
}
}
public ObjectSize Datapoint_Object_Size
{
get { return datapoint_object_size; }
set
{
datapoint_object_size = value;
OnPropertyChanged(new PropertyChangedEventArgs("datapoint_object_size"));
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (PropertyChanged != null)
{
PropertyChanged(this, e);
}
}
}
and i have define a container
public ObservableCollection<DCA_GroupAddress> _ProjectGroupAddress { get; set; } = new ObservableCollection<DCA_GroupAddress>();
my question is why i need to add these code:
GroupAddressDataGrid.Items.Clear();
GroupAddressDataGrid.ItemsSource = _ProjectGroupAddress;
in the UI class constructor? Seems that Items are not empty when the DataGrid is created so the software not use the ItemsSource. I need to clear the items before the binding works...
Thanks

Changing datagrid cell color

This is frequent question, but still don't know how to make it work. I'm performing a logger and want to set red color on cell. XAML:
<Window.Resources>
<local:LogLevelToColorConverter x:Key="colorConverter"/>
</Window.Resources>
<Grid>
<DataGrid x:Name="dgLog" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Date and time" Binding="{Binding DateTime}" Width="120"/>
<DataGridTextColumn Header="Message1" Binding="{Binding Message}">
<DataGridTextColumn.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="Foreground"
Value="{Binding Color}" />
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
<DataGridTextColumn Header="Message2" Binding="{Binding Message}" Foreground="{Binding Level,Converter={StaticResource colorConverter}}"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
Code:
namespace DGTest {
public class LogLevelToColorConverter : IValueConverter {
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
if (value is string level) {
var brush = Brushes.White;
if (level == "WARN") {
brush = Brushes.Yellow;
}
else if (level == "ERROR") {
brush = Brushes.Red;
}
return brush;
}
return Brushes.White;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
throw new NotImplementedException();
}
}
public class LogMessage {
public string DateTime { get; set; }
public string Level { get; set; }
public string Message { get; set; }
public Brush Color { get; set; }
}
public partial class MainWindow : Window {
readonly ObservableCollection<LogMessage> logMessages = new ObservableCollection<LogMessage>();
public MainWindow() {
InitializeComponent();
dgLog.ItemsSource = logMessages;
logMessages.Add(new LogMessage { DateTime = DateTime.Now.ToString(), Level = "ERROR", Message = "Test message", Color = Brushes.Red });
}
}
Tried to pass Brush in "Color" field directly - not working (Message1 column). Tried with Converter (Message2 column), still no result. Don't know what's wrong.
MainWindow View:
<Grid>
<DataGrid x:Name="dgLog" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Date and time" Binding="{Binding DateTime}" Width="120"/>
<DataGridTextColumn Header="Message" Binding="{Binding Message}">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="{Binding Color}" />
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
LogMessage Class:
public class LogMessage
{
public string DateTime { get; set; }
public string Level { get; set; }
public string Message { get; set; }
public Brush Color { get; set; }
}
MainWindow.xaml.cs:
public partial class MainWindow : Window
{
readonly ObservableCollection<LogMessage> logMessages = new ObservableCollection<LogMessage>();
public MainWindow()
{
InitializeComponent();
dgLog.ItemsSource = logMessages;
logMessages.Add(new LogMessage
{
DateTime = DateTime.Now.ToString(),
Level = "ERROR",
Message = "Test message",
Color = Brushes.Red
});
}
}
Result screenshot:

Binding an attribute to property of the itemssource collection

I have a data grid.
the item source MySource is an observableCollection<myClass>.
The class myClass has a property BackgroundOfRow - its type is Brush.
I want to bind the RowBackground attribute to this property in the xaml.
how can I do it?
my xaml now is:
<DataGrid AutoGenerateColumns="False"
ItemSource="{Binding Source={StaticResource myViewModel}, Path=MySource}">
<DataGrid.Columns>
<DataGridTextColumn Header="First Name"
Binding="{Binding Path=FirstName}"
FontFamily="Arial"
FontStyle="Italic" />
<DataGridTextColumn Header="Last Name"
Binding="{Binding Path=LastName}"
FontFamily="Arial"
FontWeight="Bold" />
</DataGrid.Columns>
</DataGrid>
You can bind the Background property in the RowStyle of DataGrid:
View:
<DataGrid ItemsSource="{Binding EmployeeColl}>
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Setter Property="Background" Value="{Binding BackgroundOfRow}"/>
</Style>
</DataGrid.RowStyle>
</DataGrid>
Model:
public class Employee
{
public int ID { get; set; }
public int Name { get; set; }
public int Surname { get; set; }
public Brush BackgroundOfRow { get; set; }
}
ViewModel:
private ObservableCollection<Employee> employeeColl;
public ObservableCollection<Employee> EmployeeColl
{
get { return employeeColl; }
set
{
employeeColl = value;
OnPropertyChanged("EmployeeColl");
}
}
private void PopulateDataGrid()
{
employeeColl = new ObservableCollection<Employee>();
for (int i = 0; i < 100; i++)
{
if(i%2==0)
employeeColl.Add(new Employee() { ID = i, BackgroundOfRow = Brushes.CadetBlue});
else
employeeColl.Add(new Employee() { ID = i, BackgroundOfRow = Brushes.Green });
}
}

C# WPF TwoWay CheckBox Binding not updating

stackoverflow!
Starting with my code:
XAML
<DataGrid Margin="25,112,25,10" Name="datGrid" RowHeight="30"
ColumnWidth="150" BorderThickness="1"
Style="{StaticResource AzureDataGrid}" IsReadOnly="False"
AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.HeaderTemplate>
<DataTemplate>
<CheckBox Content="CREATE" Name="headerCheckBox"
FontWeight="Bold" Width="Auto"
Checked="headerCheckBox_Checked"/>
</DataTemplate>
</DataGridTemplateColumn.HeaderTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding Path=IsChecked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="HorizontalAlignment" Value="Center"/>
</Style>
</DataGridTemplateColumn.CellStyle>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Username" Binding="{Binding Path=Username}"/>
<DataGridTextColumn Header="First Name" Binding="{Binding Path=FirstName}"/>
<DataGridTextColumn Header="Last Name" Binding="{Binding Path=LastName}"/>
<DataGridTextColumn Header="Email" Binding="{Binding Path=Email}"/>
</DataGrid.Columns>
</DataGrid>
And C#
public partial class MainWindow : Window
{
ObservableCollection<MyData> MyItems = new ObservableCollection<MyData>();
public MainWindow()
{
datGrid.ItemsSource = MyItems;
MyItems.Add(new MyData { IsChecked = false, Username = "apetecca", FirstName = "Anthony", LastName = "Petecca", Email = "apetecca#email.com"});
MyItems.Add(new MyData { IsChecked = true, Username = "jhalls", FirstName = "Jake", LastName = "Halls", Email = "jhalls#email.com" });
}
public class MyData
{
public bool IsChecked { get; set; }
public string Username { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
}
private void headerCheckBox_Checked(object sender, RoutedEventArgs e)
{
foreach (var item in MyItems)
{
item.IsChecked = true;
}
}
When I click on the headerCheckBox to check it, I've watched the variables in the foreach loop to see it is changing the items from false to true but doesn't visually show that on the DataGrid. However, if I manually check or uncheck the boxes, it displays correctly when going through that loop. The loop correctly sets the values but does not change the GUI display.
Everything I have seen online indicates it has to do with TwoWay mode and UpdateSourceTrigger. Both of these are set and I can't seem to find anything else on these.
Any help would be greatly appreciated!
EDIT-
I also tried changing my class to look like this
public class MyData
{
private bool _isChecked;
public bool IsChecked
{
get { return _isChecked; }
set
{
_isChecked = value;
OnPropertyChanged("IsChecked");
}
}
public string Username { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
This didn't resolve it either.
Implement INotifyPropertyChanged and then have your properties raise event to make this happen.
Something like:
public class MyData : INotifyPropertyChanged
{
private bool isChecked;
public bool IsChecked
{
get { return isChecked; }
set
{
if (isChecked != value)
{
isChecked = value;
OnPropertyChanged("IsChecked");
}
}
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}

ComboBoxColumn Issue with WPF-MVVM datagrid

I would like to add a ComboBox column in my dataGrid "Product" with the list of Suppliers. But nothing I did works. What is the good way to bind this column?
The Models:
public partial class foodSupplier
{
public foodSupplier()
{
this.products = new HashSet<product>();
}
public int idfoodSupplier { get; set; }
public string supplier { get; set; }
public virtual ICollection<product> products { get; set; }
}
public partial class product
{
public int idproduct { get; set; }
public string #ref { get; set; }
public int supplier { get; set; }
public string refsup { get; set; }
public string description { get; set; }
public int MOQ { get; set; }
public int unit { get; set; }
public decimal priceMOQ { get; set; }
public virtual foodSupplier foodSupplier { get; set; }
public virtual unit unit1 { get; set; }
}
Here my command base (ViewModel):
public class CommandBase<T> :INotifyPropertyChanged
{
#region "INotifyPropertyChanged members"
public event PropertyChangedEventHandler PropertyChanged;
//This routine is called each time a property value has been set.
//This will //cause an event to notify WPF via data-binding that a change has occurred.
protected void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
private ObservableCollection<T> collection;
public ObservableCollection<T> Collection
{
get
{
if (collection == null)
{
collection = new ObservableCollection<T>();
}
return collection;
}
set { collection = value; OnPropertyChanged("Collection");}
}
private ICommand getCommand;
private ICommand saveCommand;
private ICommand removeCommand;
public ICommand GetCommand
{
get
{
return getCommand ?? (getCommand = new RelayCommand(param => Get(),param=>CanGet()));
}
}
protected virtual bool CanGet()
{
return true;
}
public ICommand SaveCommand
{
get
{
return saveCommand ?? (saveCommand = new RelayCommand(param => Save()));
}
}
protected virtual bool CanSave()
{
return true;
}
public ICommand DeleteCommand
{
get
{
return removeCommand ?? (removeCommand = new RelayCommand(param=>Delete()));
}
}
protected virtual bool CanDelete()
{
return true;
}
}
Here the ProductViewModel:
public class ProductViewModel : CommandBase<product>
{
public Context ctx = new Context();
protected override void Get()
{
ctx.products.ToList().ForEach(supplier => ctx.products.Local.Add(supplier));
Collection = ctx.products.Local;
}
protected override bool CanGet()
{
return true;
}
protected override void Save()
{
foreach (product item in Collection)
{
if (ctx.Entry(item).State == System.Data.Entity.EntityState.Added)
{
ctx.products.Add(item);
}
}
ctx.SaveChanges();
}
}
}
Here the SupplierViewModel:
public class SupplierViewModel : CommandBase<foodSupplier>
{
public Context ctx = new Context();
protected override void Get()
{
ctx.foodSuppliers.ToList().ForEach(supplier => ctx.foodSuppliers.Local.Add(supplier));
Collection = ctx.foodSuppliers.Local;
}
protected override bool CanGet()
{
return true;
}
protected override void Save()
{
foreach (foodSupplier item in Collection)
{
if (ctx.Entry(item).State == System.Data.Entity.EntityState.Added)
{
ctx.foodSuppliers.Add(item);
}
}
ctx.SaveChanges();
}
}
Here the view:
<Page.Resources>
<vm:ProductViewModel x:Key="product"/>
<vm:SupplierViewModel x:Key="supplier"/>
</Page.Resources>
<Grid DataContext="{Binding Source={StaticResource product}}">
<StackPanel Grid.ColumnSpan="2" Margin="0,0,58,0">
<Button x:Name="BtnDelete"
Content="Delete"
Command="{Binding DeleteCommand}"/>
<Button x:Name="BtnAdd"
Content="Save"
Command="{Binding SaveCommand}"/>
<DataGrid x:Name="dataGrid" Margin="5" ItemsSource="{Binding Collection}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="id" Binding="{Binding idproduct, UpdateSourceTrigger=PropertyChanged}" Visibility="Hidden"/>
<DataGridTextColumn Header="Ref FTHK" Binding="{Binding ref, UpdateSourceTrigger=PropertyChanged}" />
<DataGridComboBoxColumn Header="Supplier" ItemsSource="{Binding Collection, Source={StaticResource supplier}}????" DisplayMemberPath="supplier" SelectedValueBinding="{Binding ????}" SelectedValuePath="idSupplier"/>
<DataGridTextColumn Header="Ref Supplier" Binding="{Binding refsup, UpdateSourceTrigger=PropertyChanged}"/>
<DataGridTextColumn Header="Description" Binding="{Binding description, UpdateSourceTrigger=PropertyChanged}"/>
<DataGridTextColumn Header="MOQ" Binding="{Binding MOQ, UpdateSourceTrigger=PropertyChanged}"/>
<DataGridTextColumn Header="Unit" Binding="{Binding unit, UpdateSourceTrigger=PropertyChanged}"/>
<DataGridTextColumn Header="Prix/MOQ" Binding="{Binding priceMOQ, UpdateSourceTrigger=PropertyChanged}"/>
</DataGrid.Columns>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding GetCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</DataGrid>
</StackPanel>
</Grid>
you have to load the SupplierCollection same as you did in loading products. I will prefer the on demand concept. Somthing like the code below
public class CommandBase<T> : INotifyPropertyChanged
{
#region "INotifyPropertyChanged members"
public event PropertyChangedEventHandler PropertyChanged;
//This routine is called each time a property value has been set.
//This will //cause an event to notify WPF via data-binding that a change has occurred.
protected void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
private ObservableCollection<T> collection;
public ObservableCollection<T> Collection
{
get
{
if (collection == null)
{
Get();
}
return collection;
}
set { collection = value; OnPropertyChanged("Collection"); }
}
private ICommand getCommand;
private ICommand saveCommand;
private ICommand removeCommand;
public ICommand GetCommand
{
get
{
return getCommand ?? (getCommand = new RelayCommand(Get, CanGet));
}
}
protected virtual bool CanGet()
{
return true;
}
protected virtual void Get()
{
//return true;
}
//public ICommand SaveCommand
//{
// get
// {
// return saveCommand ?? (saveCommand = new RelayCommand(param => Save()));
// }
//}
protected virtual bool CanSave()
{
return true;
}
//public ICommand DeleteCommand
//{
// get
// {
// return removeCommand ?? (removeCommand = new RelayCommand(param => Delete()));
// }
//}
protected virtual bool CanDelete()
{
return true;
}
}
Now you view will look like.
<Page.Resources>
<vm:ProductViewModel x:Key="product"/>
<vm:SupplierViewModel x:Key="supplier"/>
<DataTemplate x:Key="SupplierDataTemplate">
<TextBlock Text="{Binding supplier}"/>
</DataTemplate>
</Page.Resources>
<Grid>
<StackPanel>
<Grid DataContext="{Binding Source={StaticResource product}}" x:Name="ProductGrid">
<StackPanel Grid.ColumnSpan="2" Margin="0,0,58,0">
<Button x:Name="BtnDelete"
Content="Delete"
Command="{Binding DeleteCommand}"/>
<Button x:Name="BtnAdd"
Content="Save"
Command="{Binding SaveCommand}"/>
<DataGrid x:Name="dataGrid" Margin="5" ItemsSource="{Binding Collection}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="id" Binding="{Binding idproduct, UpdateSourceTrigger=PropertyChanged}" Visibility="Hidden"/>
<DataGridTextColumn Header="Ref FTHK" Binding="{Binding ref, UpdateSourceTrigger=PropertyChanged}" />
<DataGridComboBoxColumn Header="Supplier" ItemsSource="{Binding Collection, Source={StaticResource supplier}}"
DisplayMemberPath="supplier"
SelectedValueBinding="{Binding supplier}"/>
<DataGridTextColumn Header="Ref Supplier" Binding="{Binding refsup, UpdateSourceTrigger=PropertyChanged}"/>
<DataGridTextColumn Header="Description" Binding="{Binding description, UpdateSourceTrigger=PropertyChanged}"/>
<DataGridTextColumn Header="MOQ" Binding="{Binding MOQ, UpdateSourceTrigger=PropertyChanged}"/>
<DataGridTextColumn Header="Unit" Binding="{Binding unit, UpdateSourceTrigger=PropertyChanged}"/>
<DataGridTextColumn Header="Prix/MOQ" Binding="{Binding priceMOQ, UpdateSourceTrigger=PropertyChanged}"/>
</DataGrid.Columns>
<!--<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding GetCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>-->
</DataGrid>
</StackPanel>
</Grid>
</StackPanel>
</Grid>
Hope it helps

Categories

Resources