WPF ComboBox SelectionChanged command not firing - c#

I have a ComboBox,and I define its ItemTemplate.I want the combobox selectionChanged command firing when clicking the combobox item or check/uncheck the checkbox before it.Here is the xmal:
<ComboBox x:Name="DeptComboBox"
Grid.Row="2" Grid.Column="3"
IsReadOnly="True"
StaysOpenOnEdit="True"
ItemsSource="{Binding DeptDtoes}"
Text="{Binding SelectedDeptNames}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding DeptSelectedCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<ComboBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding Name}" IsChecked="{Binding IsSelected}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
And the ViewModel:
public class AddDoctorViewModel:ViewModelBase, ISingletonDependency
{
private readonly IBasicAppService _basicAppService;
public ObservableCollection<DeptDto> DeptDtoes { get; }
private string _selectedDeptNames;
public string SelectedDeptNames
{
get { return _selectedDeptNames; }
set
{
_selectedDeptNames = value;
RaisePropertyChanged(nameof(SelectedDeptNames));
}
}
private int _selectedIndex;
public int SelectedIndex
{
get { return _selectedIndex; }
set
{
_selectedIndex = value;
RaisePropertyChanged(nameof(SelectedIndex));
}
}
public RelayCommand DeptSelectedCommand { get; set; }
public AddDoctorViewModel(IBasicAppService basicAppService)
{
_basicAppService = basicAppService;
DeptDtoes = new ObservableCollection<DeptDto>(_basicAppService?.DeptDtoes);
DeptSelectedCommand = new RelayCommand(DeptSelected);
}
private void DeptSelected()
{
}
}
But the combobox selectionChanged command not firing.Can anyone help me?

<ComboBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding Name}" IsChecked="{Binding IsSelected}"
Command="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type ComboBox}},Path=DataContext.DeptSelectedCommand}" />
</DataTemplate>
</ComboBox.ItemTemplate>

Related

Same value gets selected in all comboboxes upon changing selection in one combobox in a WPF application

Hi I have a problem with binding in two cascading comboboxes. Please see below xaml code:
<DataGridTemplateColumn Width="2*" Header="Modality">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox UseLayoutRounding="True" FontFamily="{StaticResource
SiemensSansFontFamily}" FontSize="15" FontWeight="Regular"
Style="{StaticResource InputDataOrderGridComboBoxStyle}"
Margin="10 15 10 15"
Foreground="{StaticResource WhiteOpacityNinetyPercentage}"
VerticalAlignment="Top" Height="30"
Text="{Binding Modality, Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding DataContext.Modalities, Mode=TwoWay,
RelativeSource={RelativeSource FindAncestor, AncestorType=
{x:Type DataGrid }}}" DisplayMemberPath="Name"
SelectedItem="{Binding DataContext.SelectedModality,Mode
=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}">
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Width="4*" Header="Image Type">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox Name="CmbImageType" UseLayoutRounding="True" FontFamily="{StaticResource SiemensSansFontFamily}" FontSize="15"
FontWeight="Regular" Style="{StaticResource InputDataOrderGridComboBoxStyle}" Margin="10 15 10 15"
Foreground="{StaticResource WhiteOpacityNinetyPercentage}" VerticalAlignment="Top" Height ="30"
Text="{Binding ImageType, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding DataContext.ImageTypes, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}"
SelectedItem="{Binding DataContext.SelectedImageType, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}">
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
how my datagrid looks:https://i.stack.imgur.com/5lYtw.png
In View model:
public ObservableCollection Modalities { get; set; }
private ObservableCollection<string> myImageTypes;
public ObservableCollection<string> ImageTypes {
get => myImageTypes;
set
{
myImageTypes = value;
OnPropertyChanged();
}
}
private Modality mySelectedModality;
public Modality SelectedModality
{
get => mySelectedModality;
set
{
mySelectedModality = value;
OnPropertyChanged();
ImageTypes = SelectedModality.ImageTypes;
OnPropertyChanged("ImageTypes");
SelectedImageType = ImageTypes[0];
OnPropertyChanged("SelectedImageType");
}
}
In View model constructor:
Modalities = Modality.GetModalitiesList();
ImageTypes = Modalities[0].ImageTypes;
On adding new row:
Modalities = Modality.GetModalitiesList();
ImageTypes = Modalities[0].ImageTypes;
Model:
public class Modality
{
public string Name { get; set; }
public ObservableCollection<string> ImageTypes { get; private set; }
public static ObservableCollection<Modality> GetModalitiesList()
{
var modalities = new ObservableCollection<Modality> {
new Modality{ Name = "NM", ImageTypes = new ObservableCollection<string>
{
"Static",
"Dynamic",
"Gated",
"WholeBody",
"Tomo",
"Gated Tomo",
"Dynamic Tomo",
"Recon Tomo",
"Gated Recon Tomo",
"Dynamic Recon Tomo" }},
new Modality{ Name = "PT", ImageTypes = new ObservableCollection<string>
{
"Recon Tomo",
"Recon Gated Tomo",
"Recon Dynamic Tomo", }},
new Modality{ Name = "CT", ImageTypes = new ObservableCollection<string>
{
"Any"}}
};
return modalities;
}
}
The Problem is when I select any value in any ImageType combox, same value is shown in all Image type comboboxes.
Please help , how to fix this. Any input is much appreciated. Thanks.

WPF Input KeyBinding for a ListBox Item

I'm having a WPF Application, programatically I'm setting the focus to the ListBox Item, after that using UP / Down arrow I'm navigating from one Item to another Item. I need to Implement ENTER KeyEvent for that appropriate Item, it should trigger the ICommand SelectItemCommand in the ViewModel.
Consider the ViewModel Code:
public class MobileViewModel
{
public ObservableCollection<Mobile> MobileCollection { get; set; }
public MobileViewModel()
{
MobileCollection = new ObservableCollection<Mobile>()
{
new Mobile() { ID = 1, Name = "iPhone 6S", IsSelected = false },
new Mobile() { ID = 2, Name = "Galaxy S7", IsSelected = false }
}
}
public ICommand SelectItemCommand
{
get
{
return new DelegatingCommand((obj) =>
{
// Enter Key Event Operation
});
}
}
}
public class Mobile
{
public int ID { get; set; }
public string Name { get; set; }
public bool IsSelected { get; set; }
}
The XAML Code is
<ListBox ItemsSource="{Binding MobileCollection}" x:Name="KeyListBox">
<ListBox.ItemTemplate>
<DataTemplate>
<Button Command="{Binding SelectItemCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MobileViewModel}}}" CommandParameter="{Binding }">
<Button.InputBindings>
<KeyBinding Key="Enter" Command="{Binding SelectItemCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MobileViewModel}}}" CommandParameter="{Binding }" />
</Button.InputBindings>
<Button.Content>
<StackPanel>
<TextBlock Text="{Binding Name}" />
</StackPanel>
</Button.Content>
</Button>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
My requirement is to trigger the ICommand while on Keyboard ENTER Key hit. I tried the KeyBinding inside the Button, but its not happening. Kindly assist me.
The ListBox Key Binding is
<ListBox.InputBindings>
<KeyBinding Key="Enter" Command="{Binding DataContext.SelectItemCommand, ElementName=KeyListBox}"
CommandParameter="{Binding SelectedItem,
RelativeSource={RelativeSource FindAncestor, AncestorType=ListBox}}"/>
</ListBox.InputBindings>
You should specify the Element Name and bind using DataContext. Then It should be work
The Complete XAML Source Code is
<ListBox Name="KeyListBox" ItemsSource="{Binding MobileCollection}" HorizontalAlignment="Left" Height="Auto" VerticalAlignment="Top" Width="300" HorizontalContentAlignment="Stretch">
<ListBox.InputBindings>
<KeyBinding Key="Enter" Command="{Binding DataContext.SelectItemCommand, ElementName=lstBox}" CommandParameter="{Binding SelectedItem, RelativeSource={RelativeSource FindAncestor, AncestorType=ListBox}}"/>
</ListBox.InputBindings>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Button Command="{Binding DataContext.SelectItemCommand, ElementName=lstBox}" CommandParameter="{Binding }" Foreground="Black" Padding="12 10" HorizontalContentAlignment="Left">
<Button.Content>
<StackPanel>
<CheckBox IsChecked="{Binding IsSelected, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Foreground="#404040">
<CheckBox.Content>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name, IsAsync=True}" TextWrapping="Wrap" MaxWidth="270" />
</StackPanel>
</CheckBox.Content>
</CheckBox>
</StackPanel>
</Button.Content>
</Button>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
You could put the InputBinding on the ListBox itself, passing through the selected item as the command parameter.
<ListBox ItemsSource="{Binding MobileCollection}" x:Name="KeyListBox">
<ListBox.InputBindings>
<KeyBinding Key="Enter" Command="{Binding SelectItemCommand}" CommandParameter="{Binding SelectedItem, RelativeSource={RelativeSource FindAncestor, AncestorType=ListBox}}"/>
</ListBox.InputBindings>
</ListBox>

Wpf listview item selection event

I have two ListView, each list contains some row's. I want to call function after row selection. But i have a problem, event "GotFocus" firing when row selected or button in this row clicked. When i use <i:EventTrigger EventName="Selected"> it is not firing when row in table is selected. What i need to do?
Xaml:
<Grid>
<ListView Width="200" Height="200" ItemsSource="{Binding Items}" HorizontalAlignment="Left">
<ListView.ItemTemplate>
<DataTemplate>
<Button Content="{Binding .}">
</Button>
</DataTemplate>
</ListView.ItemTemplate>
<i:Interaction.Triggers>
<i:EventTrigger EventName="GotFocus">
<i:InvokeCommandAction Command="{Binding DataContext.TestCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type vm:MainWindow }}}"></i:InvokeCommandAction>
</i:EventTrigger>
</i:Interaction.Triggers>
</ListView>
<ListBox Width="200" Height="200" ItemsSource="{Binding Items}" HorizontalAlignment="Right">
<ListBox.ItemTemplate>
<DataTemplate>
<Button Content="{Binding .}">
</Button>
</DataTemplate>
</ListBox.ItemTemplate>
<i:Interaction.Triggers>
<i:EventTrigger EventName="GotFocus">
<i:InvokeCommandAction Command="{Binding DataContext.TestTestCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type vm:MainWindow }}}"></i:InvokeCommandAction>
</i:EventTrigger>
</i:Interaction.Triggers>
</ListBox>
</Grid>
Code:
namespace WpfApplication129
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
DataContext = new Data();
InitializeComponent();
}
}
public class Data
{
public ICommand TestCommand { get; set; }
public ICommand TestTestCommand { get; set; }
public List<string> Items { get; set; }
public Data()
{
TestCommand = new RelayCommand(() => Test());
TestTestCommand = new RelayCommand(() => TestTest());
Items = new List<string>();
Items.Add("first");
Items.Add("Second");
Items.Add("Third");
}
public void Test()
{
MessageBox.Show("Running");
}
public void TestTest()
{
MessageBox.Show("TestRunning");
}
}
}
There is no Selected event in ListView, you have to use SelectionChanged event.

Bind ListPicker in MVVM (Selection_Changed)

I am trying to attach a command to the event Selection_Changed of the ListPicker
I have the following code for the listpicker in my xaml :
<toolkit:ListPicker
x:name="picker" ItemsSource="{Binding Sentences}"
SelectionChanged="{Binding PickerCommand, Mode=TwoWay}" >
<toolkit:ListPicker.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding }"/>
</DataTemplate>
</toolkit:ListPicker.ItemTemplate>
</toolkit:ListPicker>
Sentences is just a list of string in my ViewModel, how can I create a simple Commad for example that will just show a MessageBox with the current selected string in the ListPicker ?
Something similar to this function that i wrote in the code Behind :
private void PickerCommand(object sender, SelectionChangedEventArgs e)
{
if (piker.SelectedItem != null)
{
MessageBox.Show(piker.SelectedItem.ToString());
}
}
EDIT :
I just created this simple function :
public void Test()
{
MessageBox.Show("Test!");
}
passed it :
PickerCommand = new RelayCommand<SelectionChangedEventArgs>(Test);
But I have the error saying that the argument that I passed is invalid, why is that ?
You need to do this:
<toolkit:ListPicker x:name="picker" ItemsSource="{Binding Sentences}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<command:EventToCommand Command="{Binding PickerCommand, Mode=OneWay}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<toolkit:ListPicker.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding }"/>
</DataTemplate>
</toolkit:ListPicker.ItemTemplate>
and then
public class MYViewModel :ViewModelBase
{
public MyViewModel()
{
PickerCommand = new RelayCommand<object>(ActionForPickerCommand);
}
public ICommand PickerCommand {get;set;}
}
Use MVVM Light, that has some classes that help in it.

ListViewItem with CheckBox IsChecked Binding to ViewModel

I have a ListView with a DataTemplate for displaying for each ListViewItem a Checkbox.
<ListView ItemsSource="{Binding TableNames}">
<ListView.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding}" IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsSelected, Mode=TwoWay}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
The ItemsSource ("TableNames") is deklared in the ViewModel like this:
private ObservableCollection<Item> _TableNames = new ObservableCollection<Item>();
public ObservableCollection<Item> TableNames
{
get { return _TableNames; }
set
{
_TableNames = value;
OnPropertyChanged("TableNames");
}
}
public class Item
{
public bool IsSelected { get; set; }
public string Name { get; set; }
public override string ToString()
{
return this.Name;
}
}
How can I bind the IsChecked from the Checkbox to the Item.IsSelected property?
My code doesn't work.
Try this
<DataTemplate>
<CheckBox Content="{Binding Name}" IsChecked="{Binding IsSelected}" />
</DataTemplate>
Remove RelativeSource
<CheckBox Content="{Binding}" IsChecked="{Binding IsSelected}" />
Since DataContext of ListViewItem will be set to instance of Item all you need to specify is path to IsSelected

Categories