I've created a DataGrid that is using AutoGeneratedColumns. Everything works as expected with the exception of the Checkbox column. When the checkbox is clicked, the data source is not updated. It seems the DataGrid needs to lose focus before the data source is updated. Is there an easy way around this, or do I need to generate the columns manually?
Xaml:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="25" />
<RowDefinition Height="*" />
<RowDefinition Height="5" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<DockPanel>
<Menu DockPanel.Dock="Top">
<MenuItem Header="_File">
<MenuItem x:Name="moNewSystem" Header="_New System" Click="moNewSystem_Click" />
<MenuItem x:Name="moSaveSystems" Header="_Save Systems" Click="moSaveSystems_Click" />
<MenuItem x:Name="moLoadSystems" Header="_Load Systems" Click="moLoadSystems_Click" />
<Separator />
<MenuItem x:Name="moExit" Header="E_xit" Click="moExit_Click" />
</MenuItem>
</Menu>
</DockPanel>
<DataGrid x:Name="dgvSystems" Grid.Row="1" ItemsSource="{Binding AllSystems, Mode=TwoWay}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" AutoGeneratingColumn="dgvSystems_AutoGeneratingColumn" />
<GridSplitter Grid.Row="2" VerticalAlignment="Stretch" />
<ListBox x:Name="lstOutput" Grid.Row="3" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
</Grid>
View Model:
public class ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
private ObservableCollection<Systems> allSystems = new ObservableCollection<Systems>();
public ObservableCollection<Systems> AllSystems
{
get { return allSystems; }
set { allSystems = value; OnPropertyChanged(); }
}
}
public class Systems : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
private MainWindow Parent;
private string symbol;
public string Symbol
{
get { return symbol; }
set { symbol = value; OnPropertyChanged(); }
}
private bool isEnabled;
public bool IsEnabled
{
get { return isEnabled; }
set
{
isEnabled = value;
OnPropertyChanged();
if (isEnabled)
StartSystem();
else StopSystem();
}
}
private void StartSystem()
{
Parent.Log("Started");
}
private void StopSystem()
{
Parent.Log("Stopped");
}
public Systems(MainWindow parent)
{
Parent = parent;
}
}
Window:
public partial class MainWindow : Window
{
public ViewModel viewModel = new ViewModel();
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
DataContext = viewModel;
foreach (var column in dgvSystems.Columns)
column.Width = new DataGridLength(1, DataGridLengthUnitType.Star);
}
private void moNewSystem_Click(object sender, RoutedEventArgs e)
{
NewSystem nsWindow = new NewSystem(this);
bool? result = nsWindow.ShowDialog();
switch(result)
{
case true:
// Add System to collection
viewModel.AllSystems.Add(nsWindow.ThisSystem);
nsWindow.Close();
break;
}
}
private void moSaveSystems_Click(object sender, RoutedEventArgs e)
{
}
private void moLoadSystems_Click(object sender, RoutedEventArgs e)
{
}
private void moExit_Click(object sender, RoutedEventArgs e)
{
}
public void Log(string message)
{
string text = string.Format("{0}: {1}", DateTime.Now, message);
lstOutput.Items.Insert(0, text);
}
}