This is my first question on here so bear with me.
I am stumped on why this ToggleButton column doesnt communicate changes to the Match model Reviewed property when toggled:
<ToggleButton
Height="auto" Foreground="White" Margin="0, 0, 10, 0"
IsChecked="{Binding Reviewed, Mode=TwoWay}">
</ToggleButton>
However, this column works fine to communicate with the Match model Reviewed property
<DataGridCheckBoxColumn Header="Test" Width="auto" Binding="{Binding Reviewed, Mode=TwoWay}"/>
I'll post some basic code to help understand my problem.
XAML Datagrid Example
- ToggleButton does not communicate changes
- DataGridCheckBoxColumn works great
<DataGrid ItemsSource="{Binding Path=ListOfBestMatches}" x:Name="DataGrid_Matches" Height="auto" Width="Auto" Margin="0,0,-4,0" VerticalAlignment="Top" HorizontalAlignment="Stretch" AutoGenerateColumns="False">
<!-- Column Headers -->
<DataGrid.Columns>
<DataGridTemplateColumn Header="Reviewed">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ToggleButton
Height="auto" Foreground="White" Margin="0, 0, 10, 0"
IsChecked="{Binding Reviewed, Mode=TwoWay}">
</ToggleButton>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridCheckBoxColumn Header="Test" Width="auto" Binding="{Binding Reviewed, Mode=TwoWay}"/>
</DataGrid.Columns>
</DataGrid>
ViewModel
public class MainWindowViewModel : BaseViewModel
{
/// <summary>
/// Property/field which holds the official list of best matches and bound to a datagrid
/// </summary>
private ObservableCollection<Match> _listOfBestMatches;
public ObservableCollection<Match> ListOfBestMatches
{
get => _listOfBestMatches;
set
{
if (_listOfBestMatches != value)
{
_listOfBestMatches = value;
this.OnPropertyChanged("ListOfBestMatches");
}
}
}
}
Model
public class Match : BaseViewModel
{
/// <summary>
/// Property which represents the state of the Check Toggle Box in the Best Matches Data grid Reviewed column
/// </summary>
private bool reviewed;
public bool Reviewed
{
get { return reviewed; }
set
{
reviewed = value;
OnPropertyChanged("Reviewed");
Debug.WriteLine("=== SET REVIEWED ===");
}
}
}
Base View Model
namespace UserFolders.ViewModels
{
/// <summary>
/// This is the base view model which all other view models will extend from.
/// This model is necesarry for notifying the UI when data has changed so it
/// can display appropriately on its own
/// </summary>
public class BaseViewModel : INotifyPropertyChanged
{
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
CodePudding user response:
Finally found the solution to your problem. I guess, the problem was how data grid cells are updated. I have for example added some text columns and wondered, that they are only updated as soon as the datagrid cell lost focus. UpdateSourceTrigger=PropertyChanged
(Which I had used before, but these things are easily forgotten^^) did the trick.
Here is the changed code along with the text columns for testing:
<DataGrid ItemsSource="{Binding Path=ListOfBestMatches}" x:Name="DataGrid_Matches" Height="auto" Width="Auto" Margin="0,0,-4,0" VerticalAlignment="Top" HorizontalAlignment="Stretch" AutoGenerateColumns="False"
>
<!-- Column Headers -->
<DataGrid.Columns>
<DataGridTextColumn Header="name" Binding="{Binding Name, UpdateSourceTrigger=PropertyChanged}" />
<DataGridTextColumn Header="name" Binding="{Binding Name, UpdateSourceTrigger=PropertyChanged}" />
<DataGridTemplateColumn Header="Reviewed">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ToggleButton
Height="auto" Foreground="White" Margin="0, 0, 10, 0"
IsChecked="{Binding Reviewed, UpdateSourceTrigger=PropertyChanged}">
</ToggleButton>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridCheckBoxColumn Header="Test" Binding="{Binding Reviewed, UpdateSourceTrigger=PropertyChanged}"/>
</DataGrid.Columns>
</DataGrid>
You only need to add the corresponding property to your VM (or delete it):
private string name;
public string Name
{
get { return name; }
set
{
name = value;
OnPropertyChanged("Name");
}
}
BTW: In case you are interested, I made a MVVM Pattern Example project for a course some time ago. It shows a bit of an updated example of the ViewModelBase
class for example as well as a few other things. You can find it here: https://github.com/TheRealRolandDeschain/DesignPatternsMVVMExample