Bind enum to combobox and bind to property - wpf

I have successfully passed the following Enum to a Combobox using the following:
public enum Color
{
Blue,
Green,
Yellow
}
public Color _color { get; set; }
public Type Colors
{
get { return typeof(Color); }
}
In the view I have the following:
<ComboBox ItemsSource="{Binding Colors, Converter={StaticResource enumConverter}}">
<ComboBox.ItemTemplate>
<DataTemplate>
<Grid>
<TextBlock Text="{Binding }" FontSize="14"/>
</Grid>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
This lets me pic a color in the box. What I want to do is to bind the chosen color to a property that's part of my viewmodel. I am very new to converters so I might be missing something.

You can bind the SelectedItem of the ComboBox to a property in your view model. The type of that property must match the type of the items generated by the enumConverter.

You can bind Combobox's SelectedItem to the property. I rename the Property to SelectedColor in the ViewModel. The PropertyChanged event is raised in the setter, so when you update the property, for example, from another method inside ViewModel, the view is notified and updated with the new value.
private Color _selectedColor;
public Color SelectedColor
{
get { return _selectedColor; }
set
{
_selectedColor = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("SelectedColor"));
}
}
}
And in the XAML
<ComboBox ItemsSource="{Binding Colors, Converter={StaticResource enumConverter}}"
SelectedItem="{Binding SelectedColor}">
...

Related

WPF Datagrid MVVM : Combobox Binding using DatagridTemplateColumn

Have a WPFDatagrid binded to combobox using Datagridtemplatecolumn. Finding difficult to get the selectedItem of the combobox binding. Have found similar examples around but that's not resolving my problem.
Please find the code snippet of my XAML and the data structure below:
public class X
{
public X ()
{
abc = new ObservableCollection<P>();
}
public ObservableCollection<P> Y
{
get { return abc; }
set { abc = value; PropertyChanged("Y"); }
}
}
public class P
{
private string id;
private string name;
public string ID
{
get
{
return id;
}
set
{
id = value;
InvokePropertyChanged("ID");
}
}
public string Name
{
get
{
return name;
}
set
{
name = value;
InvokePropertyChanged("Name");
}
}
}
I have a datastructure defined above that implements the INotifyPropertychanged interface.
<controls:DataGrid Name="datagrid" AutoGenerateColumns="False" ItemsSource="{Binding XList}" Grid.Row="0"
SelectedItem="{Binding SelectedX, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<controls:DataGrid.Columns>
<controls:DataGridTemplateColumn Header="Yl">
<controls:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding Y}"
IsSynchronizedWithCurrentItem="False" DisplayMemberPath="Name"
SelectedValue="{Binding Path=SelectedY, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, NotifyOnTargetUpdated=True}"
SelectedValuePath="SelectedY"
SelectedItem="{Binding SelectedY, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</controls:DataGridTemplateColumn.CellTemplate>
</controls:DataGridTemplateColumn>
</controls:DataGrid.Columns>
</controls:DataGrid>
Now, in view model, have a observablecollection of List of X i.e., XList and that is binded to the datagrid in the XAML. and have Y within each row of the datagrid binded to the Combobox. Have a property as SelectedY, binded to the SelectedItem of the combobox.
Have also a property as SelectedX binded to the selectedItem of the datagrid, which works fine.
Issue is not able to get the Selected Item binding of the Combobox. Not able to set the selected item for the combobox when the selection has changed.
Can anybody help me out to set the selecteditem binding of the combo box?
Where is set your datacontext ?
You can do something like that :
<controls:UserControl x:Name=MainControl>
<controls:UserControl.DataContext>
<classpath:X/>
</controls:UserControl.DataContext>
<controls:DataGrid ItemsSource={Binding YourItemsContainer}>
<controls:DataGrid.Columns>
<controls:DataGridComboBoxColumn ItemsSource={Binding ElementName=MainControl,Path=DataContext.Y}
SelectedItem={Binding ElementName=MainControl,Path=DataContext.SelectedY}
DisplayMemberPath=Name />
</controls:DataGrid.Columns>
</controls:DataGrid>
</controls:UserControl>
The idea is to set a name to the root element connected to your datacontext, then you can access to it's datacontext property easily by the path. When you are inside of a template, the datacontext is the ItemsSource objects.
Hope it will help you a little !

Binding to Property of a ComboBox's SelectedItem

I am having a hard time finding the right syntax for binding to a ComboBox's SelectedItem's property. This is the XAML I am trying to use for the binding. Where you see SelectedItem.Mode is the idea I am having difficulty with. Note that CurrentMode is in the ViewModel and has the same type as SelectedItem.Mode
<ComboBox SelectedItem.Mode="{Binding Path=CurrentMode, Mode=TwoWays}">
<ComboBox.ItemTemplate>
<DataTemplate>
<Image Source="{Binding ImageSource}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
<local:ModeItem Mode="Free" ImageSource="pencil.png"/>
<local:ModeItem Mode="Arrow" ImageSource="arrow.png"/>
</ComboBox>
A local:ModeItem looks like this
public class ModeItem : DependencyObject, INotifyPropertyChanged
{
public static readonly DependencyProperty ModeProperty = DependencyProperty.Register("Mode", typeof(AnnotationMode), typeof(ModeItem));
public AnnotationMode Mode
{
get { return (AnnotationMode)GetValue(ModeProperty); }
set { SetValue(ModeProperty, value); }
}
public string ImageSource { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
}
I am using MVVM and trying to bind the AnnotationMode (CurrentMode) of the ViewModel to that of the ComboBox's SelectedItem's AnnotationMode (Mode)
Just do this
SelectedItem="{Binding CurrentMode}
You don't have to do all this extra stuff you are doing. Note You do need to make the datacontext of the combobox is pointing to your viewmodel.
Edit :-
You should be able to do this
SelectedValue="{Binding CurrentMode, Mode=TwoWay}"
SelectedValuePath="Mode"

selectedvalue of combobox in datagrid not getting set - silverlight mvvm model

Below is the XAML snippet for my combo-box in a datagrid.
<data:DataGridTemplateColumn Header="Entry Mode">
<data:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding Path=EntryModeCombo,Mode=TwoWay}" DisplayMemberPath="Name" SelectedValuePath="Id" SelectedValue="{Binding Path=selectedEntryMode,Mode=TwoWay}" ></ComboBox>
</DataTemplate>
</data:DataGridTemplateColumn.CellTemplate>
</data:DataGridTemplateColumn>
Entrymode is an entity in the system and the Id and Name properties of this entity are used to set the DisplayMemberPath and SelectedValuePath of the combo.
public class A
{
private ObservableCollection<EntryMode> _EntryModeCombo;
public ObservableCollection<EntryMode> EntryModeCombo
{
get { return _EntryModeCombo; }
set
{
_EntryModeCombo = value;
RaisePropertyChanged("EntryModeCombo");
}
}
private string _selectedEntryMode;
public string selectedEntryMode
{
get { return _selectedEntryMode; }
set
{
_selectedEntryMode = value;
RaisePropertyChanged("selectedEntryMode");
}
}
}
In my viewModel, I am making an observable collection of the class A, and using that to bind a grid. All works well in the ADD mode, but in the edit mode, when I try to set the selected value of the combobox in the grid, it does not work. The population of the combo-box happens, but it remains unselected. Not sure why the selectedEntryMode property is getting set, but not affecting the combo selection in the grid.
Any suggestions will be appreciated.Thanks.
SelectedValue can only be used for getting value. not setting. use SelectedItem insted

ListView's ItemsSource binding not pushing changes to source

I am using WPF and Mvvm and my ListView has its ItemSource bound to an ICollectionView. How do I handle selected item change event?
Originally I had a DataGrid's ItemSource bind to the same ICollectionView and setup the collection's CurrentChanged event. Everything works fine, but not the case for a ListView.
All you have to do, as Thomas mentioned is to bind the SelectedItem Attribute of the listbox to a property in the viewmodel. To make it clear, here's an example.
Here's my view
<Grid x:Name="LayoutRoot" Background="White">
<ListView ItemsSource="{Binding Contacts}" SelectedItem="{Binding SelectedContact, Mode=TwoWay}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
And here's my ViewModel
public class MainViewModel: ViewModelBase
{
ObservableCollection<ContactViewModel> contacts;
ContactViewModel selectedContact;
public ContactViewModel SelectedContact
{
get { return selectedContact; }
set {
selectedContact = value;
base.OnPropertyChanged("SelectedContact");
}
}
public ObservableCollection<ContactViewModel> Contacts
{
get { return contacts; }
set {
contacts = value;
base.OnPropertyChanged("Contacts");
}
}
}
Everytime you try changing the selection in the listbox you'll step into the setter of the SelectedContact.
set
{
contacts = value;
base.OnPropertyChanged("Contacts");
}
Through this, you'll know that the selected contact has changed.
Using the property SelectedContact, you'll also know which of the item in your collection is selected.
You can also bind a Collection property in the ViewModel to the SelectedItems attribute of the ListView if you want to implement multiple selection.
Just bind the SelectedItem of the ListView to a property of your ViewModel

WPF checkbox IsChecked property does not change according to binding value

here is my code:
xaml side:
I use a data template to bind with item "dataType1"
<DataTemplate DataType="{x:Type dataType1}">
<WrapPanel>
<CheckBox IsChecked="{Binding Path=IsChecked, Mode=TwoWay}" Command="{Binding Path=CheckedCommand} />
<TextBlock Text="{Binding Path=ItemName, Mode=OneWay}" />
</WrapPanel>
</DataTemplate>
then I create a ComboBox with item with type "dataType1"
<ComboBox Name="comboBoxItems" ItemsSource="{Binding Path=DataItems, Mode=TwoWay}">
and here is dataType1 difinition:
class dataType1{public string ItemName{get; set;} public bool IsChecked {get; set;}}
the scenario is I prepare a list of dataType1 and bind it to the ComboBox, ItemName display flawlessly while CheckBox IsChecked value is always unchecked regardless the value of "IsChecked" in dataType1.
Is special handling needed in binding IsChecked property in CheckBox in wpf?
Peter Leung
The problem you're having here is that the CheckBox doesn't know when the value of dataType1.IsChecked changes. To fix that, change your dataType1 to:
class dataType1 : INotifyPropertyChanged
{
public string ItemName { get; set; }
private bool isChecked;
public bool IsChecked
{
get { return isChecked; }
set
{
if (isChecked != value)
{
isChecked = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("IsChecked"));
}
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
So now, when the property value is changed it will notify the binding that it needs to update by raising the PropertyChanged event.
Also, there are easier ways to do this that avoid you having to write as much boiler-plate code. I use BindableObject from Josh Smith.

Resources