ListView Not updating after RaisePropertyChangedEvent - c#

I have the following XAML
<Label Content="Player Name" Grid.Row="0" Grid.Column="0" Margin="2,0,2,0" HorizontalAlignment="Right" Foreground="White"/>
<TextBox Grid.Row="0" Grid.Column="1" Margin="2,2,2,2" Text="{Binding PlayerFirstName}"/>
<Label Content="Player Last Name" Grid.Row="1" Grid.Column="0" Margin="2,0,2,0" HorizontalAlignment="Right" Foreground="White"/>
<TextBox Grid.Row="1" Grid.Column="1" Margin="2,2,2,2" Text="{Binding PlayerLastName}"/>
<Label Content="Player College" Grid.Row="2" Grid.Column="0" Margin="2,0,2,0" HorizontalAlignment="Right" Foreground="White"/>
<ComboBox Grid.Row="2" Grid.Column="1" Margin="2,2,2,2"
ItemsSource="{Binding Colleges}" DisplayMemberPath="CollegeName"
SelectedItem="{Binding SelectedCollege}"/>
<Button Content="Add Player" Grid.Row="3" Grid.Column="1" Width="75" Margin="2,2,2,2"
Background="Blue" Foreground="White" HorizontalAlignment="Right"
Command="{Binding NewPlayer}"/>
<ListView Grid.Row="4" Grid.Column="1" Grid.ColumnSpan="1" Margin="2,2,2,2"
ItemsSource="{Binding Players, UpdateSourceTrigger=PropertyChanged}">
<ListView.View>
<GridView>
<GridViewColumn Header="First Name" Width="100" DisplayMemberBinding="{Binding First}"/>
<GridViewColumn Header="Last Name" Width="100" DisplayMemberBinding="{Binding Last}"/>
<GridViewColumn Header="College" Width="100" DisplayMemberBinding="{Binding College}"/>
</GridView>
</ListView.View>
</ListView>
Which is bound to my PlayersViewModel Class
public class PlayersViewModel : ObservableObject
{
#region Variables
private DataView _Players = Controller.PlayerView.GetData().DefaultView;
private DataView _Colleges = Controller.CollegeTableAdapter.GetData().DefaultView;
private string _PlayerFirstName;
private string _PlayerLastName;
private DataRowView _SelectedCollege;
private long _PlayerCollegeID;
#endregion
#region Bindings
public DataView Players
{
get
{
return _Players;
}
set
{
_Players = value;
RaisePropertyChangedEvent("Players");
}
}
public DataView Colleges
{
get { return _Colleges; }
set
{
_Colleges = value;
RaisePropertyChangedEvent("Colleges");
}
}
public string PlayerFirstName
{
get { return _PlayerFirstName; }
set
{
_PlayerFirstName = value;
RaisePropertyChangedEvent("PlayerFirstName");
}
}
public string PlayerLastName
{
get { return _PlayerLastName; }
set
{
_PlayerLastName = value;
RaisePropertyChangedEvent("PlayerLastName");
}
}
public DataRowView SelectedCollege
{
get { return _SelectedCollege; }
set
{
_SelectedCollege = value;
_PlayerCollegeID = _SelectedCollege.Row.Field<long>("CollegeID");
RaisePropertyChangedEvent("SelectedCollege");
}
}
public ICommand NewPlayer
{
get { return new DelegateCommand(AddPlayer); }
}
#endregion
#region Methods
private void AddPlayer()
{
Controller.PersonTableAdapter.InsertPerson(_PlayerFirstName, _PlayerLastName, _PlayerCollegeID);
Players = Controller.PlayerView.GetData().DefaultView;
}
#endregion
}
This all works great, except when I run the InsertPerson Query in my PersonTableAdapter (which works manually and I've proven to work from the program), The Players ListView doesn't update after adding a new entry.

I found out what I did wrong.
Always make sure you are Implementing the INotifyPropertyChanged Interface in your ObservableObject Class
Mine looks like this now:
public abstract class ObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChangedEvent(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
}

Related

I can't add an Entity Framework entry. System.ArgumentNullException: "The value cannot be null. Parameter name: entity"

There is a WPF form containing 8 textboxes.
<StackPanel Grid.Column="2">
<TextBox Margin="5" Width="100" Text="{Binding SelectedOrder.OrderCode}" FontSize="16" FontWeight="Normal" FontStyle="Normal"/>
<TextBox Margin="10" Width="100" Text="{Binding SelectedOrder.ClientID}" FontSize="16" FontWeight="Normal" FontStyle="Normal"/>
<TextBox Margin="10" Width="100" Text="{Binding SelectedOrder.RouteCode}" FontSize="16" FontWeight="Normal" FontStyle="Normal"/>
<TextBox Margin="10" Width="100" Text="{Binding SelectedOrder.DriverID}" FontSize="16" FontWeight="Normal" FontStyle="Normal"/>
<TextBox Margin="10" Width="100" Text="{Binding SelectedOrder.TCCode}" FontSize="16" FontWeight="Normal" FontStyle="Normal"/>
<TextBox Margin="10" Width="100" Text="{Binding SelectedOrder.Date}" FontSize="16" FontWeight="Normal" FontStyle="Normal"/>
<TextBox Margin="10" Width="100" Text="{Binding SelectedOrder.StartDate}" FontSize="16" FontWeight="Normal" FontStyle="Normal"/>
<TextBox Margin="10" Width="100" Text="{Binding SelectedOrder.EndDate}" FontSize="16" FontWeight="Normal" FontStyle="Normal"/>
<Button Margin="50" Width="100" Content="Create"
Command="{Binding AddCommand}"
/>
</StackPanel>
There is a ViewModel class that implements the transfer of data from the view to the model
public class OrderViewModel : INotifyPropertyChanged
{
private ObservableCollection<Order> orderList; //list of records in the Order table
private Order selectedOrder; // specific entry in Order
private TransportCompanyEntities transportCompanyEntities; // context?
public Order SelectedOrder
{
get { return selectedOrder; }
set
{
selectedOrder = value;
OnPropertyChanged(nameof(SelectedOrder));
}
}
public ObservableCollection<Order> OrderList
{
get { return orderList; }
set
{
orderList = value;
OnPropertyChanged(nameof(OrderList));
}
}
public OrderViewModel()
{
transportCompanyEntities = new TransportCompanyEntities();
Load Orders();
}
private void LoadOrders()
{
OrderList = new ObservableCollection<Order>(transportCompanyEntities.Order);
}
private RelayCommand addCommand;
public RelayCommand AddCommand
{
get
{
return addCommand ??
(addCommand = new RelayCommand(obj =>
{
transportCompanyEntities.Order.Add(SelectedOrder);
transportCompanyEntities.SaveChanges();
}));
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public class RelayCommand{}
When the button is clicked, an entry should be created, but an error occurs
How can i fix it?
System.ArgumentNullException: "Value cannot be null. Parameter name: entity"
I understand that I am trying to add an empty entry, but it is not clear to me why it is not created when the button is clicked.

Properties are null when calling a command method

When RefreshServices() is called, both SelectedComputerand SelectedCustomerare null, even though they are not when I actually select them.
Why?
/edit: Forgot to post the buttons' declarations in the XAML. It's updated now.
MainWindow.xaml.cs
public partial class MainWindow : Window
{
MainViewModel _main = new MainViewModel();
public MainWindow()
{
InitializeComponent();
DataContext = _main;
}
}
XAML:
<Window.Resources>
<vm:MainViewModel x:Key="viewModel" />
</Window.Resources>
<Border Margin="10">
<Grid>
<!-- Comboboxes -->
<GroupBox Header="Computer" Grid.Column="0" Grid.ColumnSpan="4" Margin="0 0 4 4">
<ComboBox ItemsSource="{Binding ComputerNames}"
SelectedItem="{Binding SelectedComputer}"
IsSynchronizedWithCurrentItem="True"
SelectedIndex="0"/>
</GroupBox>
<GroupBox Header="Customer" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="4" Margin="0 0 4 4" >
<ComboBox ItemsSource="{Binding CustomerNames}"
SelectedItem="{Binding SelectedCustomer}"
IsSynchronizedWithCurrentItem="True"
SelectedIndex="0"/>
</GroupBox>
<!-- Main list -->
<DataGrid x:Name="dataGrid" Grid.Row="2" Grid.ColumnSpan="8"
ItemsSource="{Binding Path=Services, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}"
AutoGenerateColumns="False"
IsReadOnly="True">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Width="*" Binding="{Binding DisplayName}"/>
<DataGridTextColumn Header="Status" Width="*" Binding="{Binding Status}" />
<DataGridTextColumn Header="Machine Name" Width="*" Binding="{Binding MachineName}" />
</DataGrid.Columns>
</DataGrid>
<!-- Buttons-->
<Button Grid.Row="5" Grid.Column="0" Margin="0 4 4 4" Content="Start"
Command="{Binding Path=StartServiceCommand, Source={StaticResource viewModel}}"
CommandParameter="{Binding SelectedItems, ElementName=dataGrid}"/>
<Button Grid.Row="5" Grid.Column="1" Margin="4 4 0 4" Content="Stop"
Command="{Binding Path=StopServiceCommand, Source={StaticResource viewModel}}"
CommandParameter="{Binding SelectedItems, ElementName=dataGrid}"/>
<Button Grid.Row="5" Grid.Column="3" Margin="4 4 0 4" Content="Refresh"
Command="{Binding Path=RefreshServicesCommand, Source={StaticResource viewModel}}" />
</Grid>
</Border>
MainViewModel.cs
public class MainViewModel : INotifyPropertyChanged
{
#region INotify methods
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
protected bool SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
field = value;
OnPropertyChanged(propertyName);
return true;
}
#endregion
/*---------------------------- C U S T O M E R S -----------------------------*/
#region Customer Properties
private string _selectedCustomer;
private ObservableCollection<string> _customerNames;
public string SelectedCustomer
{
get => _selectedCustomer;
set
{
SetField(ref _selectedCustomer, value);
Services = Utils.UpdatedServices(SelectedComputer, SelectedCustomer);
}
}
public ObservableCollection<string> CustomerNames
{
get => _customerNames;
set
{
SetField(ref _customerNames, value);
Services = Utils.UpdatedServices(SelectedComputer, SelectedCustomer);
}
}
#endregion
/*---------------------------- S E R V I C E S -----------------------------*/
#region Services Properties
private ObservableCollection<ServiceController> _services;
private ObservableCollection<ServiceController> _selectedServices;
public ObservableCollection<ServiceController> SelectedServices
{
get => _selectedServices;
set => SetField(ref _selectedServices, value);
}
public ObservableCollection<ServiceController> Services
{
get => _services;
set => SetField(ref _services, value);
}
#endregion
/*---------------------------- C O M P U T E R S -----------------------------*/
#region Computer Properties
private string _selectedComputer;
private ObservableCollection<string> _computerNames;
public string SelectedComputer
{
get => _selectedComputer;
set
{
SetField(ref _selectedComputer, value);
CustomerNames = Utils.UpdatedCustomerNames(SelectedComputer);
}
}
public ObservableCollection<string> ComputerNames
{
get => _computerNames;
set => SetField(ref _computerNames, value);
}
#endregion
/*---------------------------- C O M M A N D S -----------------------------*/
#region Commands
public StartServiceCommand StartServiceCommand { get; set; }
public void StartService(ObservableCollection<ServiceController> serviceControllers)
{
try
{
foreach(var service in serviceControllers)
if (service.Status != ServiceControllerStatus.Running)
service.Start();
RefreshServices();
}
catch (Exception ex) { }
}
public StopServiceCommand StopServiceCommand { get; set; }
public void StopService(ObservableCollection<ServiceController> serviceControllers)
{
try
{
foreach (var service in serviceControllers)
if (service.Status != ServiceControllerStatus.Stopped &&
service.Status != ServiceControllerStatus.StopPending)
service.Stop();
RefreshServices();
}
catch (Exception ex) { }
}
public RefreshServicesCommand RefreshServicesCommand { get; set; }
public void RefreshServices()
{
Services = Utils.UpdatedServices(SelectedComputer, SelectedCustomer);
}
#endregion
public MainViewModel()
{
#region Initialize
_services = new ObservableCollection<ServiceController>();
_computerNames = new ObservableCollection<string>();
_customerNames = new ObservableCollection<string>();
_selectedComputer = _customerNames.FirstOrDefault();
_selectedServices = new ObservableCollection<ServiceController>();
ComputerNames = new ObservableCollection<string> { Environment.MachineName, Environment.MachineName };
StartServiceCommand = new StartServiceCommand(this);
StopServiceCommand = new StopServiceCommand(this);
RefreshServicesCommand = new RefreshServicesCommand(this);
#endregion
}
}
You created two instances of MainViewModel. Whenever you see "everything in my viewmodel is null even though, at the same time, it isn't" on Stack Overflow, look for duplicate viewmodel instantiations in the XAML and the constructor.
You're getting the Commands, inexplicably, from a throwaway copy in Window.Resources that's used for nothing else. Don't do that. Delete Source={StaticResource viewModel} from those bindings, and I think they should work as they are.
Grid is a direct child of the Window and doesn't have its own DataContext, so this should be fine. Let me know if not. We can make it work without too much trouble.
<Button Grid.Row="5" Grid.Column="0" Margin="0 4 4 4" Content="Start"
Command="{Binding StartServiceCommand}"
CommandParameter="{Binding SelectedItems, ElementName=dataGrid}"/>
<Button Grid.Row="5" Grid.Column="1" Margin="4 4 0 4" Content="Stop"
Command="{Binding StopServiceCommand}"
CommandParameter="{Binding SelectedItems, ElementName=dataGrid}"/>
<Button Grid.Row="5" Grid.Column="3" Margin="4 4 0 4" Content="Refresh"
Command="{Binding RefreshServicesCommand}" />

display grid item position number in a grid observable collection

Below is my item template in a grid view.
</Grid.ColumnDefinitions>
<StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding SerialNumber}" VerticalAlignment="Center" HorizontalAlignment="Left" FontWeight="Bold" Margin="10" FontSize="25"/>
<TextBlock Text="." VerticalAlignment="Center" HorizontalAlignment="Left" FontWeight="Bold" FontSize="25" />
</StackPanel>
<Image Grid.Column="0" Margin="20" Height="100" Width="150" HorizontalAlignment="Center" Source="{Binding ImageUri,Mode=TwoWay}" VerticalAlignment="Center"/>
</StackPanel>
</Border>
</DataTemplate>
</GridView.ItemTemplate>
what i am trying to achieve is to display the item position in the collection in the TextBlock Text="{Binding SerialNumber} (if this were to be a list view, it would be row number), please how do i achieve this.
You just need to define a class with the specific properties and bind it on xaml.
I made a simple code sample for your reference:
<GridView ItemsSource="{Binding oc}">
<GridView.ItemTemplate>
<DataTemplate>
<Border>
<StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding SerialNumber}" VerticalAlignment="Center" HorizontalAlignment="Left" FontWeight="Bold" Margin="10" FontSize="25"/>
<TextBlock Text="." VerticalAlignment="Center" HorizontalAlignment="Left" FontWeight="Bold" FontSize="25" />
</StackPanel>
<Image Grid.Column="0" Margin="20" Height="100" Width="150" HorizontalAlignment="Center" Source="{Binding source,Mode=TwoWay}" VerticalAlignment="Center"/>
</StackPanel>
</Border>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
public sealed partial class MainPage : Page
{
public ObservableCollection<Test> oc { get; set;}
public MainPage()
{
this.InitializeComponent();
oc = new ObservableCollection<Test>();
oc.CollectionChanged += Oc_CollectionChanged;
for (int i=0;i<10;i++)
{
oc.Add(new Test() {SerialNumber=i,source=new BitmapImage(new Uri("ms-appx:///Assets/test.png")) });
}
this.DataContext = this;
}
private void Oc_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
{
for (int i =e.OldStartingIndex; i<oc.Count;i++)
{
oc[i].SerialNumber = i;
}
}
}
}
public class Test:INotifyPropertyChanged
{
private int _SerialNumber;
public int SerialNumber
{
get { return _SerialNumber; }
set
{
_SerialNumber = value;
RaisePropertyChanged("SerialNumber");
}
}
private BitmapImage _source;
public BitmapImage source
{
get { return _source; }
set
{
_source = value;
RaisePropertyChanged("source");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string PropertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this,new PropertyChangedEventArgs(PropertyName));
}
}
}

How do I get databinding to work with null class?

I am developing a WPF application that is pretty much an application form. It has multiple text fields. This is my first application I am doing using the MVVM model so I am sure I am missing something. I have a lot of textboxes so the code I show will concentrate on four text field, the fourth field is suppose to total as the other three change. However the databinding I have is not executing. I cannot figure out why when I type a number into the textbox txbFamO the FamilyO get statement is not executed. Am I not binding correctly? Do I not have the class Applicant initialized correctly?
Here is my XAML:
<UserControl x:Class="ApplicationForm.Views.ApplicationView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ApplicationForm"
xmlns:model="clr-namespace:ApplicationForm.Model"
xmlns:views="clr-namespace:ApplicationForm.Views"
xmlns:viewModel="clr-namespace:ApplicationForm.ViewModel"
mc:Ignorable="d"
Height="1100" Width="800" Background="#FFDAFDF2">
<Grid x:Name="grdAppForm">
<Grid x:Name="grdAppFormGrid" DataContext="{Binding Applicant}"
Height="881" Width="700" Margin="0,0,0,0">
<Label x:Name="lblFamilySize" Content="Family Size:" Height="28" Width="102" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="372,71,0,0" FontFamily="Arial" FontWeight="Bold" FontSize="16" />
<Label x:Name="lblFamO" Content="O:" Height="28" Width="27" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="471,71,0,0" FontFamily="Arial" FontWeight="Bold" FontSize="16"/>
<TextBox x:Name="txbFamO" Text="{Binding FamilyO, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Height="22" Width="20" HorizontalAlignment="Left"
VerticalAlignment="Top" Margin="496,71,0,0" FontFamily="Arial" FontSize="16"
FontWeight="Bold" BorderThickness="0,0,0,3" BorderBrush="Black" VerticalContentAlignment="Bottom"/>
<Label x:Name="lblFamA" Content="A:" Height="28" Width="25" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="516,71,0,0" FontFamily="Arial" FontWeight="Bold" FontSize="16"/>
<TextBox x:Name="tbxFamA" Text="{Binding FamilyA, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" Height="22" Width="20" HorizontalAlignment="Left"
VerticalAlignment="Top" Margin="541,71,0,0" FontFamily="Arial" FontSize="16"
FontWeight="Bold" BorderThickness="0,0,0,3" BorderBrush="Black" VerticalContentAlignment="Bottom"/>
<Label x:Name="lblFamC" Content="C:" Height="28" Width="25" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="562,71,0,0" FontFamily="Arial" FontWeight="Bold" FontSize="16"/>
<TextBox x:Name="txtFamC" Text="{Binding FamilyC, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
Height="22" Width="20" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="587,71,0,0" FontFamily="Arial" FontSize="16" FontWeight="Bold" BorderThickness="0,0,0,3" BorderBrush="Black" VerticalContentAlignment="Bottom"/>
<Label x:Name="lblEqual" Content="=" Height="28" Width="20" HorizontalAlignment="Left" VerticalAlignment="Top"
Margin="611,71,0,0" FontFamily="Arial" FontWeight="Bold" FontSize="16"/>
<TextBox x:Name="tbxFamTot" Text="{Binding FamilyTotal,
Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" IsReadOnly="True" Height="22" Width="30"
HorizontalAlignment="Left" VerticalAlignment="Top" Margin="634,71,0,0" FontFamily="Arial"
FontWeight="Bold" FontSize="16" BorderBrush="Black" BorderThickness="0,0,0,3" IsTabStop="False"
VerticalContentAlignment="Bottom"/>
</Grid>
</Grid>
My Model Code:
namespace ApplicationForm.Model
{
public class ApplicationModel
{
}
public class Applicant : INotifyPropertyChanged
{
private string familyO;
private string familyA;
private string familyC;
public string FamilyO
{
get { return familyO; }
set
{
if (familyO != value)
{
familyO = value;
RaisePropertyChanged("FamilyO");
RaisePropertyChanged("FamilyTotal");
}
}
}
public string FamilyA
{
get { return familyA; }
set
{
if (familyA != value)
{
familyA = value;
RaisePropertyChanged("FamilyA");
RaisePropertyChanged("FamilyTotal");
}
}
}
public string FamilyC
{
get { return familyC; }
set
{
if (familyC != value)
{
familyC = value;
RaisePropertyChanged("FamilyC");
RaisePropertyChanged("FamilyTotal");
}
}
}
public string FamilyTotal
{
get
{
return (Convert.ToInt16(familyO) + Convert.ToInt16(familyA) + Convert.ToInt16(familyC)).ToString();
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}
}
My ViewModel Code:
namespace ApplicationForm.ViewModel
{
class ApplicationViewModel : INotifyPropertyChanged
{
// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/sheets.googleapis.com-dotnet-quickstart.json
static string[] Scopes = { SheetsService.Scope.Spreadsheets };
static string ApplicationName = "NB Food Pantry Application";
public RelayCommand LoadApplicantCommand
{
get;
set;
}
public RelayCommand ClearDataCommand
{
get;
set;
}
public RelayCommand PrintApplicantCommand
{
get;
set;
}
public RelayCommand CloseCommand
{
get;
set;
}
public Applicant applicants;
public ApplicationViewModel()
{
applicants = new Applicant();
PrintApplicantCommand = new RelayCommand(PrintApplicant);
ClearDataCommand = new RelayCommand(ClearApplicantData);
CloseCommand = new RelayCommand(CloseApp);
}
public ObservableCollection<Applicant> Applicants
{
get;
set;
}
}
}
I have figured out my issue. I didn't create an instance of Applicants and initialize the elements.

Loop through listview to get Checkbox status

<ListView Name="listViewLoadDisableSchems" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListView.View>
<GridView>
<GridViewColumn >
<GridViewColumn.CellTemplate >
<DataTemplate >
<DataTemplate >
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Center" >
<Label Name="lblSchemeID" VerticalAlignment="Center" Margin="0" Content="{Binding Id}" Visibility="Hidden" />
<CheckBox Name="chkScheme" VerticalAlignment="Center" Margin="0,0,0,0" Content="{Binding Name}" />
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
I want to get lblSchemeID if checkbox is selected. so i can update database.
How i can do it on butten click?
You need to look at some basic MVVM patterns to get this going. Try this in the XAML:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<ListView ItemsSource="{Binding Items}">
<ListView.View>
<GridView>
<GridViewColumn>
<GridViewColumn.CellTemplate >
<DataTemplate >
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Center" >
<CheckBox VerticalAlignment="Center" Margin="0,0,0,0" Content="{Binding Name}" IsChecked="{Binding IsSelected}" />
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
<Button Grid.Row="1" Content="What is checked?" Command="{Binding GoCommand}"></Button>
and your equivalent of this in the view model & code behind:
public class MainViewModel
{
public ObservableCollection<TestItem> Items { get; set; } = new ObservableCollection<TestItem> { new TestItem() { Id = 1, Name = "Foo" }, new TestItem() { Id = 2, Name = "Bar" } };
public ICommand GoCommand => new DelegateCommand(Go);
void Go()
{
MessageBox.Show(string.Join(Environment.NewLine, Items.Where(x => x.IsSelected).Select(x => x.Name)));
}
}
public class TestItem : INotifyPropertyChanged
{
private bool _isSelected;
public int Id { get; set; }
public string Name { get; set; }
public bool IsSelected
{
get { return _isSelected; }
set
{
if (value == _isSelected) return;
_isSelected = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
DataContext = new MainViewModel();
}
}
You can get an implementation of delegate command from Google. Ditto implementations of INotifyPropertyChanged if you struggle with that.

Categories

Resources