Below is my View code. My List is being set and updated at back-end but its not reflected in front-end even though I bonded it with ListItems.
Can you please tell why is this happening? Please tell me if you need other files.
ListOfVehicle.xaml
<Window x:Class="Seris.ListOfVehicle"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="VehicalForm" Height="600" Width="700">
<Grid>
<Label Content="Add Vehicle" HorizontalAlignment="Left" Height="27" Margin="261,8,0,0" VerticalAlignment="Top" Width="85" FontWeight="Bold" FontSize="12"/>
<Label Content="SERIS CAD" HorizontalAlignment="Left" Height="30" Margin="53,8,0,0" VerticalAlignment="Top" Width="84" FontWeight="Bold"/>
<Menu x:Name="ListOfPersonnnel" HorizontalAlignment="Left" Height="32" Margin="10,35,0,0" VerticalAlignment="Top" Width="603">
<MenuItem Header="Manage Vehicle >>" />
</Menu>
<Button Name="Add_Button" CommandParameter="add" Command="{Binding OpenAddWindow_Command}" Content="Add" Height="28" Width="81" Margin="246,396,315,46"/>
<Button Name="Replace_Button" CommandParameter="replace" Command="{Binding RemoveButton_Command}" IsEnabled="{Binding isEnableReplaceButton, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Content="Replace" Height="28" Width="81" Margin="345,396,216,46"/>
<Button Name="Remove_Button" CommandParameter="remove" Command="{Binding ReplaceButton_Command}" IsEnabled="{Binding isEnableReplaceButton, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Content="Remove" Height="28" Width="81" Margin="442,396,119,46"/>
<Label x:Name="Error_Label" Content="{Binding ErrorMessage, UpdateSourceTrigger=PropertyChanged}" Foreground="Red" HorizontalAlignment="Left" Height="30" Width="100" Margin="88,206,0,224"/>
<ListView Name ="Grid" Margin="104,67,185,226" >
<DataGrid Name="DG" ItemsSource="{Binding ListItems, UpdateSourceTrigger=PropertyChanged}" SelectedItem="{Binding SelectedRow, Mode=TwoWay}" GridLinesVisibility="None" IsReadOnly="True" AutoGenerateColumns="False" BorderThickness="0">
<DataGrid.Columns>
<DataGridTextColumn Header="Vehical No" Binding="{Binding VehicalNo}"/>
<DataGridTextColumn Header="Model" Binding="{Binding Model}" />
<DataGridTextColumn Header="ManufacturingDate" Binding="{Binding ManufacturingDate}" />
<DataGridTextColumn Header="IUNo" Binding="{Binding IUNo}" />
<DataGridTextColumn Header="Personnel" Binding="{Binding PersonnelNameSelected}" />
<DataGridTextColumn Header="Unique No" Binding="{Binding UniqueNo}"/>
</DataGrid.Columns>
</DataGrid>
</ListView>
</Grid>
VehicleMainViewModel
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Seris.Models;
using System.Collections.ObjectModel;
using System.Windows.Input;
using Seris.Commands;
using Seris.ViewModels;
using System.Windows;
using System.Windows.Controls;
using System.Threading;
using System.ComponentModel;
using Seris.Views;
namespace Seris.ViewModels
{
public class VehicleMainViewModel : ObservableObject
{
#region Getters-Setters
// Static Variables...
private static bool _IsEnableReplaceButton;
public static bool IsEnableReplaceButton
{
get { return _IsEnableReplaceButton; }
set { _IsEnableReplaceButton = value; }
}
// Non-Static Variables...
private string _VehicleNo_Error;
public string VehicleNo_Error
{
get { return _VehicleNo_Error; }
set { _VehicleNo_Error = value; OnPropertyChanged("VehicleNo_Error"); }
}
private string _Model_Error;
public string Model_Error
{
get { return _Model_Error; }
set { _Model_Error = value; OnPropertyChanged("Model_Error"); }
}
private string _ManufacturingDate_Error;
public string ManufacturingDate_Error
{
get { return _ManufacturingDate_Error; }
set { _ManufacturingDate_Error = value; OnPropertyChanged("ManufacturingDate_Error"); }
}
private string _IUNo_Error;
public string IUNo_Error
{
get { return _IUNo_Error; }
set { _IUNo_Error = value; OnPropertyChanged("IUNo_Error"); }
}
private string _Personnel_Error;
public string Personnel_Error
{
get { return _Personnel_Error; }
set { _Personnel_Error = value; OnPropertyChanged("Personnel_Error"); }
}
private string _ErroMesage;
public string ErrorMessage
{
get { return _ErroMesage; }
set
{
_ErroMesage = value; OnPropertyChanged("ErrorMessage");
if (ErrorMessage.Trim() == "" || ErrorMessage == null)
HelpVisibility = "hidden";
else
HelpVisibility = "visible";
}
}
private string _HelpVisibility;
public string HelpVisibility
{
get { return _HelpVisibility; }
set { _HelpVisibility = value; OnPropertyChanged("HelpVisibility"); }
}
private static AddVehicle _addVehicle;
public static AddVehicle addVehicle
{
get
{
return _addVehicle;
}
set
{
_addVehicle = value;
}
}
// Form Components
private Guid? _UniqueNo;
public Guid? UniqueNo
{
get { return _UniqueNo; }
set
{
if (value == null || (!value.Equals(_UniqueNo)))
{
_UniqueNo = value;
OnPropertyChanged("UniqueNo");
}
}
}
private string _VehicleNo;
public string VehicleNo
{
get { return _VehicleNo; }
set
{
if (value == null || (!value.Equals(_VehicleNo)))
{
_VehicleNo = value;
EditText = _VehicleNo;
OnPropertyChanged("VehicleNo");
validateSpecificData(1);
}
}
}
private string _Model;
public string Model
{
get { return _Model; }
set
{
if (value == null || (!value.Equals(_Model)))
{
_Model = value;
EditText = _Model;
OnPropertyChanged("Model");
validateSpecificData(2);
}
}
}
private DateTime? _ManufacturingDate;
public DateTime? ManufacturingDate
{
get { return _ManufacturingDate; }
set
{
if (value == null || (!value.Equals(_ManufacturingDate)))
{
_ManufacturingDate = value;
EditText = _ManufacturingDate.ToString();
OnPropertyChanged("ManufacturingDate");
validateSpecificData(3);
}
}
}
private string _IUNo;
public string IUNo
{
get { return _IUNo; }
set
{
if (value == null || (!value.Equals(_IUNo)))
{
_IUNo = value;
EditText = _IUNo;
OnPropertyChanged("IUNo");
validateSpecificData(4);
}
}
}
private string _PersonnelNameSelected;
public string PersonnelNameSelected
{
get { return _PersonnelNameSelected; }
set
{
if (value != _PersonnelNameSelected)
{
_PersonnelNameSelected = value;
EditText = _PersonnelNameSelected;
OnPropertyChanged("PersonnelNameSelected");
}
}
}
private ObservableCollection<string> _PersonnelName;
public ObservableCollection<string> PersonnelName
{
get { return _PersonnelName; }
set
{
if (value != _PersonnelName)
{
_PersonnelName = value;
EditText = _VehicleNo;
OnPropertyChanged("PersonnelName");
}
}
}
private ObservableCollection<VehicleModel> _listItems;
public ObservableCollection<VehicleModel> ListItems
{
get { return _listItems; }
set
{
if (value == null || (!value.Equals(_listItems)))
{
_listItems = value;
}
}
}
// Other Variables
private string _EditText;
public string EditText
{
get { return _EditText; }
set
{
if (value != _EditText)
{
_EditText = value;
OnPropertyChanged("EditText");
}
}
}
private VehicleModel _SelectedRow;
public VehicleModel SelectedRow
{
get { return _SelectedRow; }
set
{
if (value != _SelectedRow)
{
_SelectedRow = value;
OnPropertyChanged("SelectedRow");
if (SelectedRow != null)
{
UniqueNo = _SelectedRow.UniqueNo;
VehicleNo = _SelectedRow.VehicleNo;
Model = _SelectedRow.Model;
ManufacturingDate = _SelectedRow.ManufacturingDate;
IUNo = _SelectedRow.IUNo;
PersonnelNameSelected = _SelectedRow.PersonnelNameSelected;
_IsEnableReplaceButton = true;
}
}
}
}
private int _Progress;
public int Progress
{
get { return _Progress; }
set { _Progress = value; OnPropertyChanged("Progress"); }
}
#endregion
// Command Variables
private ICommand _saveButton_Command;
public ICommand SaveButton_Command
{
get { return _saveButton_Command; }
set { _saveButton_Command = value; }
}
private ICommand _ReplaceButton_Command;
public ICommand ReplaceButton_Command
{
get { return _ReplaceButton_Command; }
set { _ReplaceButton_Command = value; }
}
private ICommand _RemoveButton_Command;
public ICommand RemoveButton_Command
{
get { return _RemoveButton_Command; }
set { _RemoveButton_Command = value; }
}
private ICommand _OpenAddWindow_Command;
public ICommand OpenAddWindow_Command
{
get { return _OpenAddWindow_Command; }
set { _OpenAddWindow_Command = value; }
}
#region Methods
//Static Methods...
public static void showMessage(string message)
{
MessageBox.Show(message);
}
//Non-Static Methods...
public void SaveToList(object o1)
{
try
{
// Setting Flags
ErrorMessage = "";
// To Verify Validations
validateAllData();
// ProgressBar
//Progress = 0;
//ProgressBar();
// Adding a Record
ListItems.Add(new VehicleModel(VehicleNo, Model, ManufacturingDate, IUNo, PersonnelNameSelected));
// Setting Flags etc.
IsEnableReplaceButton = false;
CloseAdd();
// Clearing Form
UniqueNo = null;
VehicleNo = null;
Model = null;
ManufacturingDate = null;
IUNo = null;
PersonnelNameSelected = null;
}
catch (Exception ex)
{
Progress = 0;
ErrorMessage = ex.Message;
}
}
public void ReplaceToList(object o1)
{
try
{
VehicleModel vm = ListItems.First(x => x.UniqueNo == UniqueNo);
int indexToRemove = ListItems.IndexOf(vm);
// Setting Flags
ErrorMessage = "";
// To Verify Validations
validateAllData();
// ProgressBar
Progress = 0;
ProgressBar();
// Replacing Record
ListItems.Insert(indexToRemove + 1, vm);
ListItems.RemoveAt(indexToRemove);
// Clearing Form
VehicleNo = null;
Model = null;
ManufacturingDate = null;
IUNo = null;
PersonnelNameSelected = null;
// Setting Flags etc.
ErrorMessage = "";
IsEnableReplaceButton = false;
}
catch (Exception ex)
{
ErrorMessage = ex.Message;
}
}
public void RemoveList(object o1)
{
VehicleModel vm = ListItems.First(x => x.UniqueNo == UniqueNo);
int indexToRemove = ListItems.IndexOf(vm);
ErrorMessage = "";
try
{
// Setting Flags
ErrorMessage = "";
Progress = 0;
// Removing Selected Record
ListItems.RemoveAt(indexToRemove);
// Clearing Form
VehicleNo = null;
Model = null;
ManufacturingDate = null;
IUNo = null;
PersonnelNameSelected = null;
// Setting Flags etc.
ErrorMessage = "";
IsEnableReplaceButton = false;
}
catch (Exception ex)
{
ErrorMessage = ex.Message;
}
}
void ProgressBar()
{
BackgroundWorker worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.DoWork += worker_DoWork;
worker.ProgressChanged += worker_ProgressChanged;
worker.RunWorkerAsync();
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 1; i <= 100; i++)
{
(sender as BackgroundWorker).ReportProgress(i);
Thread.Sleep(5);
}
}
void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
Progress = e.ProgressPercentage;
}
public void validateAllData()
{
VehicleModel tempObject = new VehicleModel(VehicleNo, Model, ManufacturingDate, IUNo, PersonnelNameSelected);
}
public void validateSpecificData(int ErrorCode)
{
VehicleModel tempObject = new VehicleModel();
switch(ErrorCode)
{
case 1: tempObject.VehicleNo=VehicleNo;break;
case 2: tempObject.Model=Model;break;
case 3: tempObject.ManufacturingDate=ManufacturingDate;break;
case 4: tempObject.IUNo=IUNo;break;
}
tempObject.ValidateSpecificData(this, ErrorCode);
}
public void OpenAdd(object o1)
{
if(addVehicle==null)
{
addVehicle = new AddVehicle();
}
addVehicle.Show();
}
public void CloseAdd()
{
if (addVehicle != null)
{
addVehicle.Close();
addVehicle = null;
}
}
#endregion
#region Constructors
public VehicleMainViewModel()
{
// Initialization
//VehicleModel vm = new VehicleModel();
ListItems = new ObservableCollection<VehicleModel>();
PersonnelName = ListOfPersonnelViewModel.PersonNameList_Updating;
//PersonnelName = new ObservableCollection<string>() { "ABC", "DEF", "GHI" };
// Setting Flags
ErrorMessage = "";
IsEnableReplaceButton = false;
// Commands Initialization
SaveButton_Command = new RelayCommand(new Action<object>(SaveToList));
ReplaceButton_Command = new RelayCommand(new Action<object>(ReplaceToList));
RemoveButton_Command = new RelayCommand(new Action<object>(RemoveList));
OpenAddWindow_Command = new RelayCommand(new Action<object>(OpenAdd));
}
#endregion
}
}
Probably you may have not created Singleton instance so possibility of creating multiple instance for each window. Below is an example for your ViewModel Singleton.
private static VehicleMainViewModel _Instance;
public static VehicleMainViewModel getInstance
{
get
{
if(_Instance==null)
{
_Instance = new VehicleMainViewModel();
}
return _Instance;
}
}
Related
I have 2 classes: ParentClass and ChildClass and both are used as datacontext for UserControl with similar hierarchy.
I want to have parent class be notified when it's custom class property has a change in one of it's variables.
public class ParentClass
{
private ChildClass _child;
private int _value;
public ChildClass Child
{
get
{
if (_child == null)
Child = new ChildClass();
return _child;
}
set
{
_child = value;
Value = _child.Score;
OnPropertyChanged(nameof(Child));
}
}
public int Value
{
get { return _value; }
set
{
_value = value;
OnPropertyChanged(nameof(Value));
}
}
}
public class ChildClass
{
private int _score;
public int Score
{
get { return _score; }
set
{
_score = value;
OnPropertyChanged(nameof(Score));
}
}
}
What I want is that on change of Score, set part of Parent class's Child property is executed and Value updated.
How do I do that?
Edit: Code
PropertyChangedNotify
internal class PropertyChangedNotify : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
protected virtual void OnPropertyChanged(string? property)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
Proficiency_Counter - xaml
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text=""/>
<Viewbox Grid.Column="1">
<ComboBox ItemsSource="{Binding ProficiencyList}" SelectedItem="{Binding Proficiency}" Margin="1">
<ComboBox.ItemTemplate>
<DataTemplate>
<Viewbox>
<TextBlock Text="{Binding}"/>
</Viewbox>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</Viewbox>
</Grid>
Proficiency_Counter_Model - aka ChildClass
internal class Proficiency_Counter_Model: PropertyChangedNotify
{
#region private
private int _proficiencyScore;
private List<char> _proficiencyList;
private char _proficiency;
private int _level;
#endregion
#region public
public int ProficiencyScore
{
get { return _proficiencyScore; }
set
{
_proficiencyScore = value;
OnPropertyChanged(nameof(ProficiencyScore));
}
}
public List<char> ProficiencyList
{
get
{
if (_proficiencyList == null)
{
ProficiencyList = new List<char>();
ProficiencyList.Add('U');
ProficiencyList.Add('T');
ProficiencyList.Add('E');
ProficiencyList.Add('M');
ProficiencyList.Add('L');
Proficiency = 'U';
}
return _proficiencyList;
}
set
{
_proficiencyList = value;
OnPropertyChanged(nameof(ProficiencyList));
}
}
public char Proficiency
{
get { return _proficiency; }
set
{
_proficiency = value;
if (Proficiency == 'U')
{
ProficiencyScore = 0;
}
else if (Proficiency == 'T')
{
ProficiencyScore = 2 + _level;
}
else if (Proficiency == 'E')
{
ProficiencyScore = 4 + _level;
}
else if (Proficiency == 'M')
{
ProficiencyScore = 6 + _level;
}
else if (Proficiency == 'L')
{
ProficiencyScore = 8 + _level;
}
OnPropertyChanged(nameof(Proficiency));
}
}
public int Level
{
get { return _level; }
set
{
_level = value;
Proficiency = _proficiency;
OnPropertyChanged(nameof(Level));
}
}
#endregion
}
General_Skill_Counter_Model - aka ParentClass
internal class General_Skill_Counter_Model: PropertyChangedNotify
{
#region private
private string _skillName;
private int _abilityMod;
private Proficiency_Counter_Model _proficiency;
private int _proficiencyMod;
private int _itemMod;
#endregion
#region public
public string SkillName
{
get
{
if (_skillName == null)
SkillName = "Lorem Impsum";
return _skillName;
}
set
{
_skillName = value;
OnPropertyChanged(nameof(SkillName));
}
}
public int SkillScore
{
get
{
return (AbilityMod + Proficiency.ProficiencyScore + ItemMod);
}
}
public int AbilityMod
{
get { return _abilityMod; }
set
{
_abilityMod = value;
OnPropertyChanged(nameof(AbilityMod));
OnPropertyChanged(nameof(SkillScore));
}
}
public Proficiency_Counter_Model Proficiency
{
get
{
if (_proficiency == null)
{
_proficiency = new Proficiency_Counter_Model();
}
return _proficiency;
}
set
{
_proficiency = value;
ProficiencyMod = _proficiency.ProficiencyScore;
OnPropertyChanged(nameof(Proficiency));
}
}
public int ProficiencyMod
{
get { return _proficiencyMod; }
set
{
_proficiencyMod = value;
OnPropertyChanged(nameof(ProficiencyMod));
OnPropertyChanged(nameof(SkillScore));
}
}
public int ItemMod
{
get { return _itemMod; }
set
{
_itemMod = value;
OnPropertyChanged(nameof(ItemMod));
OnPropertyChanged(nameof(SkillScore));
}
}
#endregion
}
Proficiency_Counter_Model is set as Proficiency_Counter's DataContext, same for Genereal_Skill_Counter, which I believe is irrelevant to this.
Ok, I figured it out. Instead of notifying the parent, I made the child part of the parent.
Sadly, this only works for single class - It would not work if I had 2 different children of the same class.
Here's the code:
internal class Proficiency_Counter_Model: PropertyChangedNotify
{
#region private
protected int _proficiencyScore;
private List<char> _proficiencyList;
private char _proficiency;
protected int _level;
#endregion
#region public
public virtual int ProficiencyScore
{
get { return _proficiencyScore; }
set
{
_proficiencyScore = value;
OnPropertyChanged(nameof(ProficiencyScore));
}
}
public List<char> ProficiencyList
{
get
{
if (_proficiencyList == null)
{
ProficiencyList = new List<char>();
ProficiencyList.Add('U');
ProficiencyList.Add('T');
ProficiencyList.Add('E');
ProficiencyList.Add('M');
ProficiencyList.Add('L');
Proficiency = 'U';
}
return _proficiencyList;
}
set
{
_proficiencyList = value;
OnPropertyChanged(nameof(ProficiencyList));
}
}
public char Proficiency
{
get { return _proficiency; }
set
{
_proficiency = value;
if (Proficiency == 'U')
{
ProficiencyScore = 0;
}
else if (Proficiency == 'T')
{
ProficiencyScore = 2 + _level;
}
else if (Proficiency == 'E')
{
ProficiencyScore = 4 + _level;
}
else if (Proficiency == 'M')
{
ProficiencyScore = 6 + _level;
}
else if (Proficiency == 'L')
{
ProficiencyScore = 8 + _level;
}
OnPropertyChanged(nameof(Proficiency));
}
}
public int Level
{
get { return _level; }
set
{
_level = value;
Proficiency = _proficiency;
OnPropertyChanged(nameof(Level));
}
}
#endregion
}
I made the ProficiencyScore property virtual so that I could override it.
internal class General_Skill_Counter_Model : Proficiency_Counter_Model
{
#region private
private string _skillName;
private int _skillScore;
private int _abilityMod;
private int _itemMod;
#endregion
#region public
public string SkillName
{
get
{
if (_skillName == null)
SkillName = "Lorem Impsum";
return _skillName;
}
set
{
_skillName = value;
OnPropertyChanged(nameof(SkillName));
}
}
public int SkillScore
{
get { return _skillScore; }
set
{
_skillScore = value;
OnPropertyChanged(nameof(SkillScore));
}
}
public int AbilityMod
{
get { return _abilityMod; }
set
{
_abilityMod = value;
OnPropertyChanged(nameof(AbilityMod));
}
}
public int ItemMod
{
get { return _itemMod; }
set
{
_itemMod = value;
OnPropertyChanged(nameof(ItemMod));
}
}
#endregion
#region override
public override int ProficiencyScore
{
get { return _proficiencyScore; }
set
{
SkillScore = _skillScore + value - _proficiencyScore;
_proficiencyScore = value;
OnPropertyChanged(nameof(ProficiencyScore));
}
}
#endregion
}
I use this codes. In this codes, I want to change each row's background color when I click the button.
I tried to bind with DataGridRow's background. But I only get BindingExpression.
I know that if I use ObservableCollection as rowdata, it will slove very easy. But I cannot use the collection because I want to bind each column's visibility, too.
I cannot slove to this problem with this code? Please some help.
<StackPanel>
<CheckBox IsChecked="{Binding IsChecked}" Content="I change the header of Column A and I hide Column B." Margin="10"/>
<Button Content="Click!" Click="Button_OnClick" Margin="10" Width="50"/>
<DataGrid IsReadOnly="True"
ItemsSource="{Binding Table}"
AutoGeneratingColumn="DataGrid_OnAutoGeneratingColumn"
x:Name="DataGrid1"
Loaded="DataGrid1_Loaded">
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Setter Property="Background" Value="{Binding MyBackground, Mode=TwoWay}"/>
</Style>
</DataGrid.RowStyle>
</DataGrid>
</StackPanel>
public partial class MainWindow : Window
{
public ViewModel _viewModel = new ViewModel();
public MainWindow()
{
InitializeComponent();
this.DataContext = _viewModel;
}
private void DataGrid_OnAutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
BindingOperations.SetBinding(e.Column,
DataGridColumn.HeaderProperty,
new Binding($"{nameof(ViewModel.ColumnHeader)}[{e.PropertyName}]")
{
Source = _viewModel
});
BindingOperations.SetBinding(e.Column,
DataGridColumn.VisibilityProperty,
new Binding($"{nameof(ViewModel.ColumnVisibility)}[{e.PropertyName}].{nameof(BindableValue_ColumnVisible<Visibility>.Value)}")
{
Source = _viewModel
});
}
private void Button_OnClick(object sender, RoutedEventArgs e)
{
}
int mCount = 0;
string[] displayedColumnOrder;
private void DataGrid1_Loaded(object sender, RoutedEventArgs e)
{
displayedColumnOrder = new string[_viewModel.Table.Columns.Count];
DataGrid _datagrid = (DataGrid)sender;
_getColumnOrder(_datagrid.Columns);
}
void _getColumnOrder(IEnumerable<DataGridColumn> columnCollection)
{
DataGridColumn[] columnArray;
int columnIndexWorking;
displayedColumnOrder = new string[columnCollection.Count()];
columnArray = columnCollection.ToArray();
foreach (var item_Column in columnCollection)
{
columnIndexWorking = item_Column.DisplayIndex;
displayedColumnOrder[columnIndexWorking] = item_Column.Header.ToString();
}
}
}
public class ViewModel : BindableBase
{
private Brush _myBackground = Brushes.AliceBlue;
public Brush MyBackground
{
get
{
return _myBackground;
}
set
{
_myBackground = value;
NotifyPropertyChanged(nameof(MyBackground));
}
}
private bool _isChecked = false;
public bool IsChecked
{
get
{
return _isChecked;
}
set
{
_isChecked = value;
if (value == true)
{
SetHeader();
SetVisible();
}
else
{
UnSetHeader();
UnSetVisible();
}
NotifyPropertyChanged(nameof(IsChecked));
}
}
public DataTable Table { get; } = new DataTable();
public Dictionary<string, string> ColumnHeader { get; } = new Dictionary<string, string>();
public Dictionary<string, BindableValue_ColumnVisible<Visibility>> ColumnVisibility { get; } = new Dictionary<string, BindableValue_ColumnVisible<Visibility>>();
public ViewModel()
{
Table.Columns.Add("A");
Table.Columns.Add("B");
Table.Columns.Add("C");
Table.Columns.Add("D");
Table.Columns.Add("E");
for (int i = 0; i < 10; i++)
{
Table.Rows.Add($"A-{i}", $"B-{i}", $"C-{i}", $"D-{i}", $"E-{i}");
}
foreach (DataColumn column in Table.Columns)
{
ColumnHeader.Add(column.ColumnName, $"Column {column.ColumnName}");
if (column.ColumnName == "B")
{
ColumnVisibility.Add(column.ColumnName, BindableValue_ColumnVisible.Create(Visibility.Collapsed));
}
else
{
ColumnVisibility.Add(column.ColumnName, BindableValue_ColumnVisible.Create(Visibility.Visible));
}
}
}
public void SetHeader()
{
ColumnHeader["A"] = "I changed Column A!!";
NotifyPropertyChanged(nameof(ColumnHeader));
}
public void SetVisible()
{
ColumnVisibility["B"].Value = Visibility.Collapsed;
}
public void UnSetHeader()
{
ColumnHeader["A"] = "Column A";
NotifyPropertyChanged(nameof(ColumnHeader));
}
public void UnSetVisible()
{
ColumnVisibility["B"].Value = Visibility.Visible;
}
}
public class BindableValue_ColumnVisible<T> : BindableBase
{
public T Value
{
get => _value;
set => SetColumnVisibleProperty(ref _value, value);
}
private T _value;
public BindableValue_ColumnVisible()
{
}
public BindableValue_ColumnVisible(T value)
{
Value = value;
}
}
public static class BindableValue_ColumnVisible
{
public static BindableValue_ColumnVisible<T> Create<T>(T value) => new BindableValue_ColumnVisible<T>(value);
}
public class BindableBase : INotifyPropertyChanged
{
protected virtual bool SetColumnVisibleProperty<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
{
return SetColumnVisibleProperty(ref field, value, null, propertyName);
}
protected virtual bool SetColumnVisibleProperty<T>(ref T field, T value, Action onChanged, [CallerMemberName]string propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
field = value;
onChanged?.Invoke();
NotifyPropertyChanged(propertyName);
return true;
}
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
}
If you add a "MyBackground" column to your DataTable, your current RowStyle and binding should work:
public ViewModel()
{
Table.Columns.Add("A");
Table.Columns.Add("B");
Table.Columns.Add("C");
Table.Columns.Add("D");
Table.Columns.Add("E");
Table.Columns.Add("MyBackground");
for (int i = 0; i < 10; i++)
{
Table.Rows.Add($"A-{i}", $"B-{i}", $"C-{i}", $"D-{i}", $"E-{i}", "Yellow");
}
...
}
If you set the column to a known string representation of a brush, such as for example "Yellow" or "Red", you don't have to something else. Else, you could use a converter that converts the value in the DataTable to a Brush.
By the way, it's pointless to set the Mode of this Binding to TwoWay.
public class MyDataTable : System.Data.DataTable {
private Brush _myBackground = Brushes.AliceBlue;
public Brush MyBackground {
get {
return _myBackground;
}
set {
_myBackground = value;
NotifyPropertyChanged(nameof(MyBackground));
}
}
}
public MyDataTable Table { get; } = new MyDataTable();
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="Background" Value="{Binding MyBackground }" />
</Style>
I want to get / count all checked items from DataGrid. I've 20 items in DataGrid as you can see in below pic. Out of 20, visible items are 14 or 13. When i mark checked on all items by clicking Select All Button, all 20 items gets mark checked. but when i count checked items by clicking Print Button, the counting shows it mark just 14. what the matter? kindly help
Datagrid:
<DataGrid HorizontalAlignment="Left" Height="265" Margin="10,74,0,0"
Name="GridTable" AutoGenerateColumns="False" VerticalAlignment="Top" Width="766" CanUserAddRows="False" IsReadOnly="False" SelectionMode="Single" SelectionUnit="Cell">
<DataGrid.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}"
Color="#0073c4"/>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridCheckBoxColumn Header="Select" Binding="{Binding IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<DataGridTextColumn Header="Code" Width="1*" IsReadOnly="True" Binding="{Binding Code}"/>
<DataGridTextColumn Header="Name" Width="1*" IsReadOnly="True" Binding="{Binding Name}"/>
</DataGrid.Columns>
</DataGrid>
SelectAll Button:
private void SelectAllBtn_Click(object sender, RoutedEventArgs e)
{
for (int i = 0; i < GridTable.Items.Count; i++)
{
var item = GridTable.Items[i];
Item itemm = (Item)GridTable.Items[i];
itemm.IsSelected = true;
var mycheckbox = GridTable.Columns[0].GetCellContent(item) as CheckBox;
if (mycheckbox != null)
{
mycheckbox.IsChecked = true;
}
}
}
Print Button click:
private void Print_Click(object sender, RoutedEventArgs e)
{
int count = 0;
for (int i = 0; i < GridTable.Items.Count; i++)
{
var item = GridTable.Items[i];
if (GridTable.Columns[0].GetCellContent(item) as CheckBox != null)
{
var mycheckbox = GridTable.Columns[0].GetCellContent(item) as CheckBox;
if ((bool)mycheckbox.IsChecked)
{
count++;
listTobePrint.Add(tableList[i]);
}
}
}
MessageBox.Show(count.ToString());
Note: this MessageBox.Show(count.ToString());
counts 14
Item.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Inventory_Control.Classes
{
class Item : INotifyPropertyChanged
{
private string id;
private string code;
private string name;
private string description;
private string quantity;
private string availableQuantity;
private string unitprice;
private string subtotal;
private string category;
private string type;
private string location;
private string index;
private bool _isSelected;
public string Id
{
get { return id; }
set
{
id = value;
NotifyPropertyChanged("Id");
}
}
public string Code
{
get { return code; }
set
{
code = value;
NotifyPropertyChanged("Code");
}
}
public string Name
{
get { return name; }
set
{
name = value;
NotifyPropertyChanged("Name");
}
}
public string Description
{
get { return description; }
set
{
description = value;
NotifyPropertyChanged("Description");
}
}
public string Quantity
{
get { return quantity; }
set
{
quantity = value;
NotifyPropertyChanged("Quantity");
}
}
public string AvailableQuantity
{
get { return availableQuantity; }
set
{
availableQuantity = value;
NotifyPropertyChanged("AvailableQuantity");
}
}
public string UnitPrice
{
get { return unitprice; }
set
{
unitprice = value;
NotifyPropertyChanged("UnitPrice");
}
}
public string SubTotal
{
get { return subtotal; }
set
{
subtotal = value;
NotifyPropertyChanged("SubTotal");
}
}
public string Category
{
get { return category; }
set
{
category = value;
NotifyPropertyChanged("Category");
}
}
public string Type
{
get { return type; }
set
{
type = value;
NotifyPropertyChanged("Type");
}
}
public string Location
{
get { return location; }
set
{
location = value;
NotifyPropertyChanged("Location");
}
}
public string Index
{
get { return index; }
set
{
index = value;
NotifyPropertyChanged("Index");
}
}
public bool IsSelected
{
get { return _isSelected; }
set
{
_isSelected = value;
NotifyPropertyChanged("IsSelected");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
It's because your DataGrid uses row virtualisation. It is telling you the truth - it only has 14 selected rows because that is all it needs to present your underlying data.
The CODE magazine article XAML Anti-Patterns: Virtualization has a great explanation.
I notice you haven't databound your DataGrid, you must be adding the rows programmatically? The correct (proper) way to access your selected items is to go to your viewmodel that contains the collection of Item objects that you've bound the DataGrid to, and iterate that collection to find the selected items.
i have a ViewModel that implements the IDataErrorInfo interface as usual.
Model
public class Computer : Model
{
public Computer(string name, string ip, string mac, string broadcastIp)
{
Name = name;
Ip = ip;
Mac = mac;
BroadcastIp = broadcastIp;
}
public Computer()
{
Name = "neuer Computer";
Mac = string.Empty;
Ip = string.Empty;
BroadcastIp = string.Empty;
}
[NotMapped]
public ComputerState ComputerState { get; set; }
public string Name { get; set; }
public string Ip { get; set; }
public string Mac { get; set; }
public string BroadcastIp { get; set; }
public virtual Room Room { get; set; }
}
ViewModel
public class ComputerViewModel : ViewModel<Computer>, IListItem
{
private bool _IsSelected;
private ComputerOperationMessage _OperationMessage = ComputerOperationMessage.NO_MESSAGE;
public ComputerViewModel(Computer computer) : base(computer)
{
}
public string Name
{
get { return Model.Name; }
set
{
Model.Name = value;
RaisePropertyChanged(nameof(Name));
}
}
public RoomViewModel Room
{
get { return App.EntityManager.Get<RoomViewModel>().FirstOrDefault(r => r.Model.Equals(Model.Room)); }
set
{
Model.Room = value.Model;
RaisePropertyChanged(nameof(Room));
}
}
public ComputerState State
{
get { return Model.ComputerState; }
set
{
if (value.Equals(Model.ComputerState))
return;
Model.ComputerState = value;
RaisePropertyChanged(nameof(State));
}
}
public string Ip
{
get { return Model.Ip; }
set
{
Model.Ip = value;
RaisePropertyChanged(nameof(Ip));
}
}
public string Mac
{
get { return Model.Mac; }
set
{
Model.Mac = value;
RaisePropertyChanged(nameof(Mac));
}
}
public string BroadcastIp
{
get { return Model.BroadcastIp; }
set
{
Model.BroadcastIp = value;
RaisePropertyChanged(nameof(BroadcastIp));
}
}
/// <summary>
/// UI indicator when a operation like shutdown, reboot, ping etc. is running
/// </summary>
public ComputerOperationMessage OperationMessage
{
get { return _OperationMessage; }
set
{
if (value.Equals(_OperationMessage))
return;
_OperationMessage = value;
RaisePropertyChanged(nameof(OperationMessage));
}
}
public bool IsSelected
{
get { return _IsSelected; }
set
{
_IsSelected = value;
RaisePropertyChanged(nameof(IsSelected));
}
}
public override string ToString()
{
return Name;
}
protected override string ValidateProperty(string property)
{
var computers = App.EntityManager.Get<ComputerViewModel>().ToList();
switch (property)
{
case nameof(Name):
if (string.IsNullOrEmpty(Name))
{
return "Bezeichnung erwartet";
}
if (computers.Any(c => c.Name == Name))
{
return "Bezeichnung bereits vergeben";
}
break;
case nameof(Ip):
if (string.IsNullOrEmpty(Ip))
{
return "Ip erwartet";
}
if (!NetworkCommand.ValidateIp(Ip))
{
return "Ip ungültig";
}
if (computers.Any(c => c.Ip == Ip))
{
return "Ip bereits vergeben";
}
break;
case nameof(Mac):
if (string.IsNullOrEmpty(Mac))
{
return "Mac erwartet";
}
if (!NetworkCommand.ValidateMac(Mac))
{
return "Mac ungültig";
}
if (computers.Any(c => c.Mac == Mac))
{
return "Mac bereits vergeben";
}
break;
case nameof(BroadcastIp):
if (string.IsNullOrEmpty(BroadcastIp))
{
return "Broadcast Ip erwartet";
}
if (!NetworkCommand.ValidateIp(Ip))
{
return "Broadcast Ip ungültig";
}
break;
case nameof(Room):
if (Room == null)
return "Raum wählen";
break;
}
return string.Empty;
}
public abstract class ViewModel : INotifyPropertyChanged, IDataErrorInfo
{
private string _ErrorMessage;
private bool _HasErrors;
public ViewModel()
{
SaveCommand = new RelayCommand(SaveAction);
}
public bool HasErrors
{
get { return _HasErrors; }
set
{
_HasErrors = value;
RaisePropertyChanged(nameof(HasErrors));
}
}
public ICommand SaveCommand { get; }
public Model Model { get; protected set; }
public string this[string property]
{
get
{
_ErrorMessage = ValidateProperty(property);
RaisePropertyChanged(nameof(Error));
HasErrors = !string.IsNullOrEmpty(Error);
return Error;
}
}
public string Error
{
get { return _ErrorMessage; }
}
public event PropertyChangedEventHandler PropertyChanged;
private void SaveAction(object obj)
{
if (Model != null && Model.Id == 0)
{
App.EntityManager.Add(Model);
}
App.EntityManager.Save();
}
protected virtual string ValidateProperty(string property)
{
return string.Empty;
}
protected void RaisePropertyChanged(string property)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
}
}
public abstract class ViewModel<T> : ViewModel where T : Model
{
protected ViewModel(T model)
{
Model = model;
base.Model = model;
}
public new T Model { get; }
public long Id => Model.Id;
}
XAML:
<Label Content="{StaticResource NameString}" />
<TextBox Text="{Binding Path=Name, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}" />
<Label Content="{StaticResource IpString}" />
<TextBox Text="{Binding Path=Ip,ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}" />
<Label Content="{StaticResource MacString}" />
<TextBox Text="{Binding Path=Mac, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}" />
<Label Content="{StaticResource BroadcastIpString}" />
<TextBox Text="{Binding Path=BroadcastIp, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}" />
<Label Content="{StaticResource RoomString}" />
<ComboBox ItemsSource="{Binding Path=Rooms}" SelectedItem="{Binding Path=Room, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}" />
<GridSplitter Height="25" />
<Button x:Name="SaveButton"
HorizontalAlignment="Right"
Command="{Binding Path=SaveCommand}"
Content="{StaticResource SaveIcon}"
IsEnabled="{Binding Path=CanSave,
Converter={StaticResource TrueToFalseConverter},
UpdateSourceTrigger=PropertyChanged}" />
Calling code in class that implements ICommand interface:
var viewModel = parameter as ComputerViewModel;
_Editor = new ComputerEditor();
_Editor.CloseButtonCommand = new RelayCommand(CloseCommand);
_Editor.SaveButton.Click += (s, e) =>
{
App.EntityManager.Add(_Editor.ComputerEditViewModel.Model);
App.EntityManager.Save();
_Editor.IsOpen = false;
(Application.Current.MainWindow.Content as Grid).Effect = null;
};
if (viewModel == null)
{
_Editor.DataContext = new ComputerEditViewModel(new Computer());
_Editor.Title = Application.Current.FindResource("ComputerAddString").ToString();
}
else
{
_Editor.DataContext = new ComputerEditViewModel(viewModel.Model);
_Editor.Title = Application.Current.FindResource("ComputerEditString").ToString();
}
OpenChildWindow(_Editor);
My problem:
When i create a new entity without any initial values the IDataErrorInfo is executed all the time but the error (red border and label) is only shown when the new entity properties has valid initial values.
Control images
The (1) is the initial controlstate. The first textbox ('Name') has a default value that comes from the entity contructor. All other values (Textboxes) are just empty.
At this point my validation is working in my viewmodel for all textboxes/properties but only the first textbox get the red border and label when the validation fails, cause of the valid start value!
For the other properties i have to set a valid (initial) value before the red border and label is shown (when validation fails, cause of property change) although i check if the textbox/property is empty.
As i said, the validation is working in the viewmodel all the time but the view only shows the red border and label when the initial value is valid against my implementation.
Hoping this question is not to weird.
Feel free to ask anything if something is just unclear
Best regards
Dustin
I have a WPF user control that contains a combo box:
<UserControl
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:telerik="http://schemas.telerik.com/2008/xaml/presentation" x:Class="Hartville.SalesScriptApplication.Views.SalesScriptEditorGroups"
mc:Ignorable="d"
xmlns:events="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WPF4"
xmlns:hartvm="clr-namespace:Hartville.SalesScript.ViewModels;assembly=Hartville.SalesScript.ViewModels"
d:DesignHeight="106" d:DesignWidth="909" Background="#FFF3EDED">
<UserControl.Resources>
<ResourceDictionary>
<hartvm:ViewLocator x:Key="HartvilleLocator" d:IsDataSource="True" />
</ResourceDictionary>
</UserControl.Resources>
<UserControl.DataContext>
<Binding Source="{StaticResource HartvilleLocator}" Path="ScriptEditorGroups" />
</UserControl.DataContext>
<Border>
<Grid Margin="5,10,0,20">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Margin="0,10,0,20">
<TextBlock TextWrapping="Wrap" Text="Selected Script Group:"/>
<ComboBox Width="250" Margin="10,0,0,0" HorizontalAlignment="Left" ItemsSource="{Binding ScriptGroups}" SelectedItem="{Binding SelectedScriptGroup}"
DisplayMemberPath="Name" >
<events:Interaction.Triggers>
<events:EventTrigger EventName="SelectionChanged">
<cmd:EventToCommand Command="{Binding ScriptGroupSelectedCommand}" PassEventArgsToCommand="False" />
</events:EventTrigger>
</events:Interaction.Triggers>
</ComboBox>
</StackPanel>
</Border>
</UserControl>
NOTE: We are using MVVM light framework. The view locator that you see is just a class that instantiates the view model which you will see referenced in the data context portion.
When something is selected from the combo box and the edit button is clicked, the user can update the name and save it. However, when the user clicks save, you can see the changed selection in the combobox but the selected item still contains the original name. So, for example, I select the option "Hello World" from the combo box. I change the name to "FOOBAR" and click save. I update the selected item in the code (and I can see that the property is changing). When I check the combo box I see "FOOBAR" but the selected value still says "Hello World". Also, "Hello World" no longer exists in the combobox (obviously because I just updated it.
Here is the code for the view model:
using System.Windows.Input;
using System.Collections.ObjectModel;
using GalaSoft.MvvmLight.Command;
using Hartville.Common.Controls.ViewModels;
using Hartville.Common.Controls.ViewModels.Validation;
using Hartville.SalesScript.ViewModels.Messages;
using Hartville.Values.Sales;
using System.Linq;
namespace Hartville.SalesScript.ViewModels.Scripts
{
public class ScriptEditorGroups: CommonViewModelBase
{
private ObservableCollection<ScriptHeader> _scriptGroups;
private ObservableCollection<Script> _scripts;
private ScriptHeader _selectedScriptGroup;
private Script _selectedScript;
private bool _isScriptGroupActive;
private string _groupName;
private bool _shouldEnableScriptGroup;
private bool _shouldShowGroupEditPanel;
private bool _shouldUseDefaultScript;
private bool _shouldShowScriptSelection;
public ICommand EditSelectedCommand { get; set; }
public ICommand NewGroupCommand { get; set; }
public ICommand SaveCommand { get; set; }
public ICommand ScriptGroupSelectedCommand { get; set; }
public ObservableCollection<ScriptHeader> ScriptGroups
{
get { return _scriptGroups; }
set { SetPropertyValue(ref _scriptGroups, value); }
}
public ObservableCollection<Script> Scripts
{
get { return _scripts; }
set { SetPropertyValue(ref _scripts, value); }
}
public ScriptHeader SelectedScriptGroup
{
get { return _selectedScriptGroup; }
set { SetPropertyValue(ref _selectedScriptGroup, value ); }
}
public Script SelectedScript
{
get { return _selectedScript; }
set { SetPropertyValue(ref _selectedScript, value); }
}
public bool IsScriptGroupActive
{
get { return _isScriptGroupActive; }
set { SetStructPropertyValue(ref _isScriptGroupActive, value); }
}
public string GroupName
{
get { return _groupName; }
set { SetStructPropertyValue(ref _groupName, value); }
}
public bool ShouldEnableScriptGroup
{
get { return _shouldEnableScriptGroup; }
set { SetStructPropertyValue(ref _shouldEnableScriptGroup, value); }
}
public bool ShouldShowGroupEditPanel
{
get { return _shouldShowGroupEditPanel; }
set { SetStructPropertyValue(ref _shouldShowGroupEditPanel, value); }
}
public bool ShouldUseDefaultScript
{
get { return _shouldUseDefaultScript; }
set { SetStructPropertyValue(ref _shouldUseDefaultScript, value); }
}
public bool ShouldShowScriptSelection
{
get { return _shouldShowScriptSelection; }
set { SetStructPropertyValue(ref _shouldShowScriptSelection, value); }
}
public bool IsEdit { get; set; }
public bool IsNew { get; set; }
protected override void RegisterForMessages()
{
MessengerService.Register<BeginSalesScriptEditorMessage>(OnBeginSalesScriptEditor);
EditSelectedCommand = new RelayCommand(OnEdit);
NewGroupCommand = new RelayCommand(OnNewGroup);
SaveCommand = new RelayCommand(OnSave);
ScriptGroupSelectedCommand = new RelayCommand(OnScriptGroupSelected);
}
private void OnBeginSalesScriptEditor(BeginSalesScriptEditorMessage message)
{
ScriptGroups = new ObservableCollection<ScriptHeader>(SalesService.GetAllScriptHeader());
Scripts = new ObservableCollection<Script>(SalesScriptCache.Scripts);
ShouldEnableScriptGroup = false;
ShouldShowGroupEditPanel = false;
ShouldShowScriptSelection = false;
IsEdit = false;
IsNew = false;
}
private void OnEdit()
{
if(SelectedScriptGroup == null) return;
IsEdit = true;
ShouldShowGroupEditPanel = true;
ShouldShowScriptSelection = true;
GroupName = SelectedScriptGroup.Name;
SelectedScript = SalesScriptCache.Scripts.FirstOrDefault(s => s.ScriptId == SelectedScriptGroup.StartScriptId);
}
private void OnNewGroup()
{
IsNew = true;
GroupName = string.Empty;
ShouldShowGroupEditPanel = true;
ShouldShowScriptSelection = false;
}
private void OnSave()
{
ThreadManagement.ExecuteInSeparateThread(ProcessScriptUpdate);
}
private void OnScriptGroupSelected()
{
if(SelectedScriptGroup == null) return;
MessengerService.Send(ScriptHeaderSelectedMessage.Create(SelectedScriptGroup));
ShouldEnableScriptGroup = true;
}
protected override void SetDesignTimeInfo(){}
protected void ResetValues()
{
ShouldEnableScriptGroup = false;
ShouldShowGroupEditPanel = false;
IsScriptGroupActive = false;
IsEdit = false;
IsNew = false;
ShouldShowScriptSelection = false;
}
private int CreateNewScriptGroup()
{
var scriptHeader = new ScriptHeader
{
Name = GroupName,
IsActive = IsScriptGroupActive
};
MessengerService.Send(ScriptHeaderSelectedMessage.Create(scriptHeader));
return SalesService.ScriptHeaderInsertUpdate(scriptHeader);
}
private int EditExistingScriptGroup()
{
if(SelectedScriptGroup == null) return 0;
var scriptHeader = new ScriptHeader
{
Name = GroupName,
IsActive = IsScriptGroupActive,
ScriptHeaderId = SelectedScriptGroup.ScriptHeaderId,
StartScriptId = SelectedScript.ScriptId
};
MessengerService.Send(ScriptHeaderSelectedMessage.Create(scriptHeader));
return SalesService.ScriptHeaderInsertUpdate(scriptHeader);
}
private void ProcessScriptUpdate()
{
var returnId = 0;
if (IsNew)
returnId = CreateNewScriptGroup();
else if (IsEdit)
returnId = EditExistingScriptGroup();
ScriptGroups = new ObservableCollection<ScriptHeader>(SalesService.GetAllScriptHeader());
SelectedScriptGroup = ScriptGroups.FirstOrDefault(h => h.ScriptHeaderId == returnId);
ResetValues();
}
}
}
How do I fix this issue?
EDIT:
This is the SetPropertyValue method that calls the notify:
public virtual void SetPropertyValue<T>(ref T currentValue, T newValue, Action<T> extraFunction = null, Action voidAfterSetAction = null) where T : class
{
if (currentValue == newValue) return;
currentValue = newValue;
PropertyHasChanged();
if (extraFunction != null) extraFunction(newValue);
if (voidAfterSetAction != null) voidAfterSetAction();
}
EDIT:
This is the entire base class that holds the property change code:
using System;
using System.ComponentModel;
using System.Diagnostics;
using GalaSoft.MvvmLight;
using Hartville.Common.Controls.Messaging;
using Hartville.Common.Controls.Modules;
using Hartville.Common.Controls.ViewModels.Validation;
using Hartville.Common.Controls.WebServices;
using Hartville.Common.Threading;
namespace Hartville.Common.Controls.ViewModels
{
public abstract class CommonViewModelBase : ViewModelBase, IDataErrorInfo
{
public string this[string columnName]
{
get
{
var validationReturn = ValidationManager.Validate(columnName);
OnValidationComplete();
return validationReturn;
}
}
public string Error
{
get { return null; }
}
protected CommonViewModelBase()
{
ValidationManager = ValidationManager.Start(this);
RegisterForMessages();
if (IsInDesignMode) SetDesignTimeInfo();
}
public virtual void Reset()
{
IsProcessing = false;
}
public virtual void OnValidationComplete()
{
}
public virtual void SetPropertyValue<T>(ref T currentValue, T newValue, Action<T> extraFunction = null, Action voidAfterSetAction = null) where T : class
{
if (currentValue == newValue) return;
currentValue = newValue;
PropertyHasChanged();
if (extraFunction != null) extraFunction(newValue);
if (voidAfterSetAction != null) voidAfterSetAction();
}
public virtual void SetPropertyValue<T>(ref T currentValue, T newValue, Action extraFunction) where T : class
{
if (currentValue == newValue) return;
currentValue = newValue;
PropertyHasChanged();
if (extraFunction != null) extraFunction();
}
public virtual void SetStructPropertyValue<T>(ref T currentValue, T newValue, Action<T> extraFunction = null, Action voidActionAfterSetAction = null)
{
currentValue = newValue;
PropertyHasChanged();
if (extraFunction != null) extraFunction(newValue);
if (voidActionAfterSetAction != null) voidActionAfterSetAction();
}
public virtual void SetStructPropertyValue<T>(ref T currentValue, T newValue, Action extraFunction)
{
currentValue = newValue;
PropertyHasChanged();
if (extraFunction != null) extraFunction();
}
public virtual void SetValue<T>(ref T currentValue, T newValue, Action<T> voidOldValueAction = null, Action voidAfterSetAction = null) where T : class
{
var oldVal = currentValue;
if (currentValue == newValue) return;
currentValue = newValue;
PropertyHasChanged();
if (voidOldValueAction != null) voidOldValueAction(oldVal);
if (voidAfterSetAction != null) voidAfterSetAction();
}
protected abstract void RegisterForMessages();
protected abstract void SetDesignTimeInfo();
protected void SendModalCloseMessage()
{
MessengerService.Send(ModalCommandMessage.Create(ModalOptions.Close));
}
protected void SendModalOpenMessage(ModalName windowName, Guid? customID = null)
{
MessengerService.Send(ModalCommandMessage.Create(ModalOptions.Open, windowName, customID));
}
private void PropertyHasChanged()
{
var currentFrame = 2;
var frame = new StackFrame(currentFrame);
var propertyName = string.Empty;
if (frame.GetMethod().Name.Length > 4) propertyName = GetPropertyName(frame);
while (!frame.GetMethod().Name.StartsWith("set_"))
{
currentFrame++;
frame = new StackFrame(currentFrame);
if (frame.GetMethod().Name.Length > 4) propertyName = GetPropertyName(frame);
}
RaisePropertyChanged(propertyName);
}
private static string GetPropertyName(StackFrame frame)
{
return frame.GetMethod().Name.Substring(4);
}
}
}
You need to implement iNotifyPropertyChanged and call PropertyChanged in
public ScriptHeader SelectedScriptGroup
{
set { SetPropertyValue(ref _selectedScriptGroup, value ); }
}
Adding to what Blam has already mentioned, you must implement INotifyPropertyChanged interface in your CommonViewModelBase or current view model. And you should call the PropertyChanged method for all the property setters whose values you are changing after the Datacontext has been assigned to the view.
public ScriptHeader ScriptGroups
{
set { SetPropertyValue(ref _selectedScriptGroup, value );
PropertyChanged("SelectedScriptGroup ");
}
}
public ScriptHeader SelectedScriptGroup
{
set { SetPropertyValue(ref _selectedScriptGroup, value );
PropertyChanged("SelectedScriptGroup");
}
}
Else, there is no way for your View to know that the property value to which the control is binding has changed. For implementation, please refer to Property Changed Implementation