开发者

Listbox with checkbox not triggering selected item when checkbox is checked/unchecked

开发者 https://www.devze.com 2023-02-06 00:05 出处:网络
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 che

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...
  }
}


  1. You should probably bind IsChecked to the IsSelected property of the container ListBoxItem
  2. That way you can handle the SelectionChanged event of the ListBox and react to any changes. (use e.AddedItems and e.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);
        }
    }
0

精彩评论

暂无评论...
验证码 换一张
取 消