I have a datagrid within a tabitem that has a Checkbox Data Template column. The data is bound to an observable collection that contains a CheckboxChecked column inside the class. When this item is changed in the class and mapped in the binding, the INotifyPropertyChanged fires correctly.
However, what I'm trying to do is fire an event similar to this Binding Checkbox Click event inside ItemsControl to viewmodel
I've now read so many articles and tried a variety of solutions that I'm not sure which part of my code is causing the issue.
Let me know if there's anything extra to know?
This is the XAML for the TabItem
<TabItem x:Name="AutoDealingTab" Header="AutoDealing" DataContext="{Binding Source={StaticResource advm}}" IsSelected="{Binding Path=AutoDealingTabSelected, Mode =TwoWay, UpdateSourceTrigger=PropertyChanged}" >
<Grid Width="1000">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<DataGrid ItemsSource="{Binding EpicParams}" AlternatingRowBackground="LightGray" CanUserAddRows="False" AutoGenerateColumns="False" CanUserSortColumns="False" CanUserReorderColumns="False">
<DataGrid.Columns>
<DataGridTemplateColumn Width="85" >
<DataGridTemplateColumn.Header>
<TextBlock Text="Start Automated Dealing" Width="75" TextAlignment="Center" TextWrapping="Wrap"/>
</DataGridTemplateColumn.Header>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox x:Name="EpicCheckbox" Command="{Binding Clicked, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}" CommandParameter="{Binding IsChecked, RelativeSource={RelativeSource Self}}" HorizontalAlignment="Center"></CheckBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Epic" Binding="{Binding Epic}" IsReadOnly="True"/>
<DataGridTextColumn Header="Market State" Binding="{Binding MarketState}" IsReadOnly="True" Width="*"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
</TabItem>
These are the Windows Resources
<Window x:Class="AutoTradingSystem.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:viewModel="clr-namespace:AutoTradingSystem_v07.ViewModel"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
xmlns:Converters="clr-namespace:AutoTradingSystem_v07.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:model="clr-namespace:AutoTradingSystem_v07.Model"
xmlns:local="clr-namespace:AutoTradingSystem_v07.ViewModel"
mc:Ignorable="d" FontFamily="Microsoft Sans Serif" FontSize="11" FontWeight="Normal"
Title="Auto Trading System v07-05" Height="800" Width="1300" Background="#FFDADADA"
>
<!-- Loaded="MainWindow_Loaded" -->
<Window.Resources>
<viewModel:ApplicationViewModel x:Key="avm" />
<viewModel:AutoDealingViewModel x:Key="advm" />
<model:EpicParamsMainModel x:Key="admm" />
</Window.Resources>
This is the AutoDealingViewModel
namespace AutoTradingSystem_v07.ViewModel
{
public class AutoDealingViewModel : ViewModelBase
{
//This will bind to the DataGrid instead of the TestEntities
public CollectionViewSource ViewSource { get; set; }
//Notice no OnPropertyChange, just a property
private static AutoDealingViewModel instance;
public ObservableCollection<EpicParamsMainModel.EpicParamsModel> EpicParams { get; set; }
public AutoDealingViewModel()
{
instance = this;
EpicParams = new ObservableCollection<EpicParamsMainModel.EpicParamsModel>();
//Initialize the view source and set the source to your observable collection
this.ViewSource = new CollectionViewSource();
ViewSource.Source = EpicParams;
InitialiseViewModel();
Clicked = new RelayCommand(ExecuteClicked);
}
private void ExecuteClicked()
{
}
public ICommand Clicked { get; }
private void ExecuteClicked(object isChecked)
{
if ((bool)isChecked) { }
int I = 0;
}
public static AutoDealingViewModel getInstance()
{
return instance;
}
// Other code below
}
}
This is the ViewModelBase
namespace AutoTradingSystem_v07.ViewModel
{
public abstract class ViewModelBase : INotifyPropertyChanged
{
public enum TradeSubscriptionType
{
Opu = 0,
Wou = 1,
Confirm = 2
}
public static string CurrentAccountId;
public void InitialiseViewModel()
{
SmartDispatcher smartDispatcher = (SmartDispatcher)SmartDispatcher.getInstance();
smartDispatcher.setViewModel(ApplicationViewModel.getInstance());
if (RunningEnv.RunEnvironment.Type() == "PRD")
{
_Env = "live";
}
else { _Env = "demo"; }
//Clicked = new RelayCommand(ExecuteClicked());
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
}
protected virtual void OnPropertyChanged(PropertyChangedEventArgs args)
{
var handler = PropertyChanged;
handler?.Invoke(this, args);
}
}
}
namespace AutoTradingSystem_v07.Model
{
public class EpicParamsMainModel
{
public class EpicParamsModel : INotifyPropertyChanged
{
private string _epic;
public string Epic
{
get
{
return _epic;
}
set
{
_epic = value;
OnPropertyRaised("Epic");
}
}
private bool _checkboxChecked;
public bool CheckboxChecked
{
get
{
return _checkboxChecked;
}
set
{
_checkboxChecked = value;
OnPropertyRaised("CheckboxChecked");
}
}
private String _marketState;
public String MarketState
{
get
{
return _marketState;
}
set
{
_marketState = value;
OnPropertyRaised("MarketState");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyRaised(string propertyname)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyname));
}
}
}
}
You have an incorrect command binding. Most likely, you need a command from an "advm" instance.
Also, most likely, you have an incorrect CommandParameter binding. You need to pass a collection element to the parameter, not the value of one of the properties.
It is also very doubtful to use CollectionViewSource at the ViewModel level.
But your code is not enough to give precise advice on the correct implementation.
<CheckBox x:Name="EpicCheckbox"
Command="{Binding Clicked, Source={StaticResource advm}}"
CommandParameter="{Binding}"
HorizontalAlignment="Center"/>
private void ExecuteClicked(object obj)
{
EpicParamsModel item = (EpicParamsModel) obj;
if (item.IsChecked)
{
// Some Code
}
int I = 0;
}