Listbox with checkbox not triggering selected item when checkbox is checked/unchecked
My application is developed using wpf MVVM pattern where i have a list box which shows a set of operations to be selected with checkbox to check/uncheck. I need to get the selected item whenever a checkbox is checked / unchecked. I am binding the IsChecked property of checkbox to property in my model and selecteditem property of listbox to property in my viewmodel. Whenever i check/uncheck the frist item in the list the selected item event is triggering however the same is not getting triggered when i check/uncheck any item other than the first selected item in the list. I need to capture the changes whenever the user does any changes to listbox items. Here is my view:
<ListBox Height="280" Width="Auto" ItemsSource="{Binding OperationsInfoCol}" SelectionMode="Multiple"
SelectedItem="{Binding Path=SelectedOperationItem,UpdateSourceTrigger=PropertyChanged}" IsEnabled="{Binding CanEnableListBox}">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding OperationName}"
IsChecked="{Binding Path=IsOperationSelected,Mode=TwoWay}" IsEnabled="{Binding Path=CanEnableOperation,Mode=TwoWay}"/>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="IsSelected" Value="{Binding IsOperationSelected,Mode=TwoWay}"/>
<Setter Property="IsEnabled" Value="{Binding CanEnableOperation,Mode=TwoWay}"/>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
ViewModel:
public OperationsInfo SelectedOperationItem
{
get
{
开发者_开发百科 return m_oOperationSelected;
}
set
{
if (value != null)
{
m_oOperationSelected = value;
OnPropertyChanged("SelectedOperationItem");
if (null != m_oOperationSelected)
{
ObservableCollection<OperationsInfo> oCol = new ObservableCollection<OperationsInfo>();
//if (m_oOperationSelected.CanEnableOperation)
{
foreach (OperationsInfo itm in OperationsInfoCol)
{
if (itm.OperationId == m_oOperationSelected.OperationId && m_oOperationSelected.CanEnableOperation)
{
itm.IsOperationSelected = !m_oOperationSelected.IsOperationSelected;
}
oCol.Add(itm);
}
OperationsInfoCol.Clear();
OperationsInfoCol = oCol;
}
}
}
}
}
Model:
public class OperationsInfo {
private string m_strOperationName;
private int m_nOperationId;
private bool m_bIsOperationSelected;
private bool m_bCanEnable;
private LicenseManagerViewModel m_VMLicenseManager;
public bool IsOperationSelected
{
get
{
return m_bIsOperationSelected;
}
set
{
m_bIsOperationSelected = value;
LicenseManagerVM.OperationInfoChecked = value;
}
}
}
Because you set SelectionMode="Multiple", you cannot use SelectedItem.
You also cannot bind to SelectedItems because this property is read-only.
Not all is lost because in your code you bind IsSelected to IsOperationSelected
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="IsSelected"
Value="{Binding IsOperationSelected,Mode=TwoWay}"/>
</Style>
</ListBox.ItemContainerStyle>
So now you can process the selected items using IsOperationSelected as indicated in the following example in your ViewModel:
foreach (var operationsInfo in OperationsInfoCol)
{
if ( operationsInfo.IsOperationSelected)
{
// do something...
}
}
- You should probably bind
IsChecked
to theIsSelected
property of the containerListBoxItem
- That way you can handle the
SelectionChanged
event of theListBox
and react to any changes. (usee.AddedItems
ande.RemovedItems
to find out what changes where made.)
Some code example:
<ListBox ItemsSource="{Binding Data}" SelectionChanged="ListBox_SelectionChanged" SelectionMode="Extended">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding Name}" IsChecked="{Binding RelativeSource={RelativeSource AncestorType=ListBoxItem}, Path=IsSelected}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Behind:
private void ListBox_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
ListBox lb = sender as ListBox;
if (e.AddedItems.Count > 0)
{
foreach (Employee emp in e.AddedItems.Cast<Employee>()) MessageBox.Show("Added: " + emp.Name);
}
if (e.RemovedItems.Count > 0)
{
foreach (Employee emp in e.RemovedItems.Cast<Employee>()) MessageBox.Show("Removed: " + emp.Name);
}
}
精彩评论