How to retrieve selected RadioButton of dynamic generated RadioButtons in WPF Mvvm - c#

Using WPF and MVVM pattern, I got a Listbox dynamically filled with Radio Buttons.
<ListBox ItemsSource="{Binding SupportedNtgs}" VerticalAlignment="Stretch" Background="Transparent">
<ListBox.ItemTemplate>
<DataTemplate>
<RadioButton GroupName="SupportedNtgsRadioButtonList" Content="{Binding Item2}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
and in my ViewModel i got a property
public Ntg SelectedNtg
{
get { return VariantInfo.Ntg; }
set
{
if (VariantInfo.Ntg == value) { return; }
VariantInfo.Ntg = value;
RaisePropertyChanged("SelectedNtg");
}
}
The SupportedNtgs the ListBox is bound to is an IEnumerable
public IEnumerable<Tuple<Ntg, String>> SupportedNtgs
{
get
{
if (this.supportedNtgs == null) {
this.supportedNtgs = new List<Tuple<Ntg, string>>();
foreach (var item in this.provider.SupportedNtgs) {
this.supportedNtgs.Add(new Tuple<Ntg, string>(item, EnumHelper<Ntg>.Description(item)));
}
}
return this.supportedNtgs;
}
}
Can anybody tell me what is the easiest way to store the user selection in my SelectedNtg property, without making any changes to my Ntg class? Thank you
thank you

here you go
added binding to SelectedItem with SelectedNtg SelectedItem="{Binding SelectedNtg}"
your xaml
<ListBox ItemsSource="{Binding SupportedNtgs}"
VerticalAlignment="Stretch" Background="Transparent"
SelectedItem="{Binding SelectedNtg}" >
<ListBox.ItemTemplate>
<DataTemplate>
<RadioButton GroupName="SupportedNtgsRadioButtonList"
Content="{Binding Item2}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
this will push the selected item to your property in your view model hence u'll get the data you are looking for

Related

Bind selected item to view model

What is required to bind a ListBox selectedItem to my ViewModel?
The view models SelectedClient is always null.
The ClientSelected is successfully called through a command called ClientClickedCommand. But when I try to access the view models SelectedClient in the ClientSelected method its null and throws an exception.
XAML
<ListBox x:Name="lbSlaves" Width="300" Grid.Row="1" ItemsSource="{Binding Slaves}" ScrollViewer.HorizontalScrollBarVisibility="Disabled"
SelectedItem="{Binding SelectedClient, Mode=TwoWay}"
>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding Checked ,Mode=TwoWay}"/>
<Button
Command="{Binding ElementName=MainGrid, Path=DataContext.ClientClickedCommand}"
>
<TextBlock Text="{Binding MachineName, Mode=OneWay}" />
</Button>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
VIEVMODEL (bound to DataContext)
private MyClient _selectedClient;
public MyClient SelectedClient
{
get {
return _selectedClient;
}
set
{
if (value != _selectedClient)
{
_selectedClient = value;
NotifyPropertyChanged("SelectedClient");
}
}
}
public string _infoText;
public string InfoText {
get {
return _infoText;
}
set {
if (value != _infoText)
{
_infoText = value;
NotifyPropertyChanged("InfoText");
}
}
}
private void ClientSelected()
{
var message = " - " + SelectedClient.MachineName + " was clicked";
InfoText += message;
}
ClientClickedCommand = new Command(ClientSelected, ()=> true);
public ICommand ClientClickedCommand
{
get;
set;
}
UPDATE: Im now trying to bind SelectedClient through CommandParameter like this
<ListBox x:Name="lbSlaves" Width="600" Grid.Row="1"
ItemsSource="{Binding Slaves}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" >
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<WrapPanel Orientation="Horizontal" Width="150" Height="60">
<CheckBox IsChecked="{Binding Checked ,Mode=TwoWay}"/>
<TextBlock Text="{Binding MachineName, Mode=OneWay}" />
<Button
Content="Do something"
Command="{Binding ElementName=MainGrid, Path=DataContext.ClientClickedCommand}"
CommandParameter="{Binding ElementName=MainGrid, Path=DataContext.SelectedClient, Mode=TwoWay}" />
<Button Content="Do another thing>" />
</WrapPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
The button might swallow the mouse click, but besides that, it's not clear where your SelectedClient property resides. It seems like it's in the MyClient class, whereas it should be in at the same level of Slaves.
Edit:
if you want to keep your own button use CommandParameter somewhat like this:
Command="{Binding ElementName=MainGrid, Path=DataContext.ClientClickedCommand}" CommandParameter="{Binding}"
I'm not sure about the works of new Command (...) but there are commands that take parameters so the next part should look like this:
private void ClientSelected(MyClient client)
{
SelectedClient = client;
var message = " - " + SelectedClient.MachineName + " was clicked";
InfoText += message;
}
Most people have already told you the problem - the button inside your ListViewItem is consuming your click event. When you assign a command to a button, WPF will, in the background, subscribe to the button's click event. Default behavior of handling click event is to set e.Handled = true;, which causes other event arising from this single mouse click to stop working.
It is not too clear whether you have separate use for SelectedClient and the command. If all you want to know is that the user has clicked on that ListViewItem, you can simply not use commands.
public MyClient SelectedClient
{
get
{
return _selectedClient;
}
set
{
if (value != _selectedClient)
{
_selectedClient = value;
ClientSelected();
NotifyPropertyChanged("SelectedClient");
}
}
}
If selecting the ListViewItem has different objective from the button, then you need to consider why you need one button for each ListViewItem. Logically, if all the items need to do something of similar nature, you can put the button outside of the ListView. This way, the button does not mess up your ListView.

SelectedIndex or SelectedItem of ListPicker with DataTemplate

I am using Listpicker to allow users to select color.
So i used a Toolkit Listpicker with a DataTemplate that includes Textbox to display its list items. What I want is when the page loads, the previously selected color(item) gets automatically selected. But it is giving me an obvious 'System.InvalidOperationException' exception because the items are not added simply but via datatemplate textbox. Please help me :
<toolkit:ListPicker x:Name="BackgroundColor" FullModeHeader="Select Background Color:" Header="Background Color:" BorderThickness="0" FullModeItemTemplate="{StaticResource PickerFullModeItemTemplate}" ItemTemplate="{StaticResource PickerItemTemplate}" Background="#FF09043C" SelectionChanged="BackgroundColor_SelectionChanged" >
</toolkit:ListPicker>
<phone:PhoneApplicationPage.Resources>
<DataTemplate x:Name="PickerItemTemplate">
<TextBlock Text="{Binding BackGroundColorString}" />
</DataTemplate>
<DataTemplate x:Name="PickerFullModeItemTemplate" >
<Grid x:Name="rootGrid" Margin="0">
<StackPanel Orientation="Horizontal">
<TextBlock Name="BackgroundColor"
Text="{Binding BackGroundColorString}"
/>
</StackPanel>
</Grid>
</DataTemplate>
</phone:PhoneApplicationPage.Resources>
if (SunderGutkaSettings.Contains(SG_KEY_BACKGROUNDCOLOR)) //check if key is not present, read value
{
if (BackGroundColorList.Count != 0)//test if list if not empty
{
var ListPickerBackGroundColorRead = BackGroundColorList[singletonInstance.SelectedFontColorIndex] as BackGroundlistPickerClass; //pull whole class
string ListPickerBackGroundColorReadString = ListPickerBackGroundColorRead.BackGroundColorString;
int ListPickerBackGroundColorReadStringToIndex = BackGroundColorList.FindIndex(x => x.BackGroundColorString.StartsWith(ListPickerBackGroundColorReadString));
BackgroundColor.SelectedIndex = ListPickerBackGroundColorReadStringToIndex; //DISABLE FOR testing
}
Actually, on simplyfing my code :
BackgroundColor.SelectedIndex = 0; Doesnt work
nor does
BackgroundColor.SelectedItem="Red";
Help me
To Set the Item,
This.BackgroundColor.SelectedItem = YourObject;
This is how you get selecteditem of ListPicker, probably you need to cast to the object you bind to the list Picker
private void BackgroundColor_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var item = (sender as ListPicker).SelectedItem;
}

listbox highlights the selecteditem even after coming back in mvvm windows phone app

I have a listbox in my application which is populated with an observable collection and it shows the items correctly in the listbox. this listbox is in a panorama item page.when user taps on any item it will navigate to a new page.
But after user comes back to the previous page where listbox is displayed, the same item is already selected and here if user taps on it again nothing happens.is there a way to fix this so that the same item is not still selected by default after returning from its page?
the view is shown below:
<ListBox x:Name="lstSavedSource" ItemsSource="{Binding SavedDataSource}"
SelectedItem="{Binding SelectedSource,Mode=TwoWay}"
Grid.Row="1" Margin="0,10,0,0">
<ListBox.ItemTemplate >
<DataTemplate>
<TextBlock Foreground="White" FontSize="20" Text="{Binding SavedSourceName}" TextWrapping="Wrap" ></TextBlock>
<TextBlock Foreground="White" FontSize="20" Text="{Binding SavedSourceid}" TextWrapping="Wrap"></TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
And the ViewModel has the following collection:
private ObservableCollection<DataSource> _SavedDataSource = new ObservableCollection<DataSource>();
public ObservableCollection<DataSource> SavedDataSource
{
get
{
ObservableCollection<DataSource> savedDataSource = new ObservableCollection<DataSource>();
savedDataSource = DataSource.GetSaved();
return savedDataSource;
}
set
{
this._SavedDataSource = value;
RaisePropertyChanged("SavedDataSource");
}
}
Before navigating to the next page, set the SelectedIndex property to -1
listbx.SelectedIndex = -1;

Bind .sdf query to listbox

Can anyone help me with this problem i want to bind the following results.
public IList<bankingCategory> bankingInfo()
{
IList<bankingCategory> bankList = null;
using (dataContext context = new dataContext(globalInfo.strConnectionString))
{
IQueryable<bankingCategory> query = from c in context.bankcategorees select c;
bankList = query.ToList();
}
return bankList;
}
set item source from code behind
MyListBox.ItemsSource =bankingInfo();
You need to set customize your list box template like below
<Grid>
<ListBox Name="MyListBox">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Property1}"></TextBlock>
<TextBlock Text="{Binding Path=Property2}"></TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>

Checkbox in Listbox to select multiple items and add it to another listbox using MVVM

Using MVVM,
I have two listboxes which contains Checkboxes and data is binded from database.
The Items which are checked in first Listbox want to add it in Second listbox.
First ListBox:
<pmControls:pmListBox SelectionMode="Multiple" Grid.Row="1" Margin="3" ItemsSource="{Binding ParcelFacilities}" >
<interactivity:Interaction.Triggers>
<interactivity:EventTrigger EventName="SelectionChanged">
<shared:EventToCommandTrigger Command="{Binding Listbox_SelectionChangeCommand}" />
</interactivity:EventTrigger>
</interactivity:Interaction.Triggers>
<pmControls:pmListBox.ItemTemplate >
<DataTemplate >
<pmControls:pmCheckBox Content="{Binding Title}" Margin="3" Width="200" IsChecked="{Binding checkedParcelFacility}" >
</pmControls:pmCheckBox>
</DataTemplate>
</pmControls:pmListBox.ItemTemplate>
Second ListBox:
<pmControls:pmListBox SelectionMode="Multiple" Grid.Row="1" Margin="3" ItemsSource="{Binding Selected_ParcelFacilities}"
Height="100">
<pmControls:pmListBox.ItemTemplate >
<DataTemplate >
<pmControls:pmCheckBox Content="{Binding Title}" Margin="3" Width="200" ></pmControls:pmCheckBox>
</DataTemplate>
</pmControls:pmListBox.ItemTemplate>
In ViewMOdel:
I have handled SelectionChanged Event For first Listbox and tryied to add checked element to the collection
Named as Selected_ParcelFacilities and Binded it to Second Listbox.
public ParcelViewModel(IModalDialogService modalDialogService, IMessageBoxService messageBoxService)
{
parcelFacilities = new ObservableCollection<Parcel_Facility>();
Selected_ParcelFacilities = new ObservableCollection<Parcel_Facility>();
Selected_ParcelFacilities.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(Selected_ParcelFacilities_CollectionChanged);
}
void Selected_ParcelFacilities_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
OnPropertyChanged("Selected_ParcelFacilities");
}
private void Executelistbox_SelectionChangeCommand(EventToCommandArgs args)
{
bool a = checkedParcelFacility;
foreach (Parcel_Facility item in parcelFacilities)
{
if (Selected_ParcelFacilities != null)
{
Selected_ParcelFacilities.Add(item);
}
}
}
But using above code all items from first listbox are adding to second ,
i am not getting how to check wheather its cheked or not.
Please Help.
you can simply bind your second list box to SelectedItems of your first one. this would work with real selection in listbox first.
<ListBox x:Name="second" ItemsSource="{Binding Elementname=first, Path=SelectedItems, Mode=OneWay}"/>
another approach is to use a ICollectionView with filter for your second listbox. the filter simply handle the checkedParcelFacility Property and the second listbox is bind to the ICollectionView.

Categories