Это не Калибро, но вы сказали, что все в порядке.
Я удаляю свойства sessionInMins и sessionAmout, чтобы сделать ответ короче, вы можете добавить его так же, как и другое свойство.
Сначала я добавляю INotifyPropertyChanged в Model, я также делаю PascalCase для свойства (заглавная буква). PascalCase не нужен, но это наиболее распространенное соглашение.
public class PackageModel : INotifyPropertyChanged
{
private int _Id;
public int Id
{
get { return _Id; }
set
{
if (value != _Id)
{
_Id = value;
NotifyPropertyChanged();
}
}
}
private string _SessionName;
public string SessionName
{
get { return _SessionName; }
set
{
if (value != _SessionName)
{
_SessionName = value;
NotifyPropertyChanged();
}
}
}
private bool _IsActive;
public bool IsActive
{
get { return _IsActive; }
set
{
if (value != _IsActive)
{
_IsActive = value;
NotifyPropertyChanged();
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Я изменяю ВМ только для того, чтобы иметь List of Packages и SelectedPackage, я удаляю List из имени Packages и делаю его множественным надстройками. Также создайте конструктор по умолчанию, чтобы заполнить список разработчиков. Как вы также предлагаете, дополнительное свойство сейчас не нужно, просто используйте SelectedPackage позже.
public class MainViewModel : INotifyPropertyChanged
{
public MainViewModel()
{
Packages = new List<PackageModel>()
{
new PackageModel()
{
Id = 1, SessionName="Session1", IsActive = true
},
new PackageModel()
{
Id = 2, SessionName="Session2", IsActive = false
}
};
}
private PackageModel _SelectedPackage;
public PackageModel SelectedPackage
{
get { return _SelectedPackage; }
set
{
if (value != _SelectedPackage)
{
_SelectedPackage = value;
NotifyPropertyChanged();
}
}
}
private List<PackageModel> _Packages;
public List<PackageModel> Packages
{
get { return _Packages; }
set
{
if (value != _Packages)
{
_Packages = value;
NotifyPropertyChanged();
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
А также добавить вид. Делайте ручные привязки. При изменении элемента в сетке текстовое поле и флажок обновляются автоматически, а также при изменении значений в текстовом поле или флажке также обновляется DataGrid.
<Window.DataContext>
<local:MainViewModel/>
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<TextBox Width="210" Margin="5 5" HorizontalAlignment="Left" Grid.Row="0" Grid.Column="0" Text="{Binding SelectedPackage.SessionName, Mode=TwoWay}"/>
<StackPanel Grid.Row="1">
<CheckBox Margin="5 5" Content="Is Active?" IsChecked="{Binding SelectedPackage.IsActive, Mode=TwoWay}"/>
</StackPanel>
<DataGrid ItemsSource="{Binding Packages,Mode=TwoWay,NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged }"
SelectedItem="{Binding SelectedPackage, Mode=TwoWay}"
Grid.Row="2"
AutoGenerateColumns="False"
CanUserAddRows="False"
CanUserDeleteRows="False"
CanUserSortColumns="False"
CanUserReorderColumns="False"
CanUserResizeRows="False">
<DataGrid.Columns>
<DataGridTextColumn Header="ID" Binding="{Binding Id}" Visibility="Hidden" IsReadOnly="True"/>
<DataGridTextColumn Header="Name" Binding="{Binding SessionName}" Width="120" IsReadOnly="True"/>
<DataGridCheckBoxColumn IsReadOnly="True" Header="Is Active?" Binding="{Binding IsActive}" Width="*"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
Дайте мне знать, если решение работает для вас!