Toggle CheckBox inside a ViewCell in Xmarin.Forms - checkbox

I would like to know how to toggle the current checkbox inside my ListView - ViewCell on item tapped event.
<ListView x:Name="listViewCities"
ItemSelected="ListViewCities_ItemSelected"
ItemTapped="ListViewCities_ItemTapped">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal">
<CheckBox x:Name="chkSelectedCity" />
<Label Text="{Binding Name}"
FontSize="Medium"
VerticalOptions="CenterAndExpand" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Here is my item tapped event.
private void ListViewCities_ItemTapped(object sender, ItemTappedEventArgs e)
{
//Here i want to toggle the current check box as true
//something like chkSelectedCity.checked = true;
}

You can use MVVM to bind a ViewModel for ListView , when data of model changed , UI will update along with that .
Such as creating a CellClass as follow :
public class CellClass : INotifyPropertyChanged
{
public string Name { set; get; }
private bool selected { get; set; }
public bool Selected
{
set
{
if (selected != value)
{
selected = value;
OnPropertyChanged("Selected");
}
}
get
{
return selected;
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Then setting some data for CellClass in a new created class (ListViewModel) :
public class ListViewModel
{
public List<CellClass> cellItems { set; get; }
public ListViewModel()
{
cellItems = new List<CellClass>();
cellItems.Add(new CellClass() { Name = "One", Selected = false });
cellItems.Add(new CellClass() { Name = "Two", Selected = false });
cellItems.Add(new CellClass() { Name = "Three", Selected = false });
cellItems.Add(new CellClass() { Name = "Four", Selected = false });
cellItems.Add(new CellClass() { Name = "Five", Selected = false });
cellItems.Add(new CellClass() { Name = "Six", Selected = false });
}
}
Now Xaml code will as follow :
<ListView x:Name="listViewCities"
ItemSelected="listViewCities_ItemSelected"
ItemTapped="ListViewCities_ItemTapped">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal">
<CheckBox x:Name="chkSelectedCity"
IsChecked="{Binding Selected}"/>
<Label Text="{Binding Name}"
FontSize="Medium"
VerticalOptions="CenterAndExpand" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
In ContentPage can deal with the ListViewCities_ItemTapped method and binding model for ListView :
public MainPage()
{
InitializeComponent();
ListViewModel listViewModel = new ListViewModel();
listViewCities.ItemsSource = listViewModel.cellItems;
}
private void ListViewCities_ItemTapped(object sender, ItemTappedEventArgs e)
{
//Here i want to toggle the current check box as true
//something like chkSelectedCity.checked = true;
var model = e.Item as CellClass;
if (model.Selected)
{
model.Selected = false;
}
else
{
model.Selected = true;
}
Console.WriteLine("clicked");
}
The effect :
This is the sample project link for reference , you can have a look when have time .

add a bool property to your model
public bool Selected { get; set; }
then bind your checkbox to it
<CheckBox IsChecked="{Binding Selected}" />
then in your handler
private void ListViewCities_ItemTapped(object sender, ItemTappedEventArgs e)
{
var item = (MyClass)e.Item;
item.Selected = !item.Selected;
}

Related

Issue with Combo box Item Template

Please find the below code.
public enum SortByType
{
[Display(Name = "Y Value")]
Y_Value,
[Display(Name = "X Value")]
X_Value,
[Display(Name = "Z Value")]
Z_Value,
}
public class ViewModel : INotifyPropertyChanged
{
ObservableCollection<SortByType> sortList;
SortByType selectedType;
public ViewModel()
{
SortList = new ObservableCollection<SortByType>(Enum.GetValues(typeof(SortByType)).OfType<SortByType>().ToList());
}
public ObservableCollection<SortByType> SortList
{
get
{
return sortList;
}
set
{
sortList = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SortList)));
}
}
public SortByType SelectedType
{
get
{
return selectedType;
}
set
{
selectedType = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedType)));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
public partial class MainWindow : Window
{
public MainWindow()
{
DataContext = new ViewModel();
(DataContext as ViewModel).SelectedType = SortByType.Y_Value;
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
(DataContext as ViewModel).SortList.Clear();
(DataContext as ViewModel).SortList = new ObservableCollection<SortByType>(Enum.GetValues(typeof(SortByType)).OfType<SortByType>().ToList());
}
}
<Grid>
<StackPanel VerticalAlignment="Center">
<ComboBox ItemsSource="{Binding SortList}"
SelectedItem="{Binding SelectedType}">
<ComboBox.ItemTemplate>
<DataTemplate>
<Label Content="{Binding}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<Button Height="25" Width="150" Content="Details" Click="Button_Click"/>
</StackPanel>
</Grid>
Just, Clear the collection and re-initialize the combo box item source on button click event. On this time I have noticed that the Data error shown on the combo box. Can anyone explain what is the exact problem whether it may be a memory issue or some thing i have missed while implement the Item Template
The value of SelectedType must be present in the source collection. It's not when you assign the source property to a new list of new values, unless you set explicitly set it to any of these new values:
private void Button_Click(object sender, RoutedEventArgs e)
{
var viewModel = DataContext as Win32ViewModel;
viewModel.SortList = new ObservableCollection<SortByType>(Enum.GetValues(typeof(SortByType)).OfType<SortByType>().ToList());
viewModel.SelectedType = viewModel.SortList.FirstOrDefault(x => x == viewModel.SelectedType);
}

WPF Update count of item when button is pushed

new to WPF and programming here I am trying to update an item in a ListView when a button is pushed if the item already exists in that ListView, for example a user inputs CAR and CAR is already in the ListView the CAR count should go from 1 to 2.
This is my InventoryItem class:
public class InventoryItem
{
public string Name { get; set; }
public int Count { get; set; }
}
Here is my ViewModel
public class ViewModel : ViewModelBase
{
private InventoryItem _item;
private int _count;
private ObservableCollection<InventoryItem> _inventoryItems;
private ICommand _addItem;
public InventoryItem Item
{
get
{
return _item;
}
set
{
_item = value;
NotifyPropertyChanged("Item");
}
}
public int Count
{
get { return _count; }
set { _count = value; NotifyPropertyChanged("Count"); }
}
public ObservableCollection<InventoryItem> InventoryItems
{
get
{
return _inventoryItems;
}
set
{
_inventoryItems = value;
NotifyPropertyChanged("Items");
}
}
public ICommand AddItem
{
get
{
if (_addItem == null)
{
_addItem = new RelayCommand(ParamArrayAttribute => this.Submit(), null);
}
return _addItem;
}
}
public ViewModel()
{
Item = new InventoryItem();
InventoryItems = new ObservableCollection<InventoryItem>();
InventoryItems.CollectionChanged += new NotifyCollectionChangedEventHandler(InventoryItems_CollectionChanged);
}
void InventoryItems_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
NotifyPropertyChanged("Items");
NotifyPropertyChanged("Count");
}
private void Submit()
{
if (InventoryItems.Any(p => p.Name == Item.Name))
{
InventoryItems.First(x => x.Name == Item.Name).ItemCount++;
}
else
{
InventoryItems.Add(Item);
}
}
}
Here is my View
<ListView x:Name="listBox" ItemsSource="{Binding InventoryItems}" Grid.Row="0" HorizontalAlignment="Stretch" Height="Auto" Margin="10,10,10,60" VerticalAlignment="Stretch">
<ListView.Resources>
<Style TargetType="GridViewColumnHeader">
<Setter Property="Visibility" Value="Collapsed"/>
</Style>
</ListView.Resources>
<ListView.View>
<GridView>
<GridViewColumn DisplayMemberBinding="{Binding Name}" Width="Auto"/>
<GridViewColumn DisplayMemberBinding="{Binding ItemCount}" Width="Auto"/>
</GridView>
</ListView.View>
</ListView>
Whenever an item that exists in the list is typed in it appears that the InventoryItems ObservableCollection is being updated however InventoryItems_CollectionChanged event is not being fired so the ListView is not being updated. Isn't the collection changing so that event should be fired to update the ListView or am I not understanding the Binding and the event?
You need to notify about property changes in the InventoryItem class to update the changes of ItemCount in the ListView.
Quick solution:
public class InventoryItem : ViewModelBase
{
public string Name
{
get { return _name; }
set
{
if (_name != value)
{
_name = value;
NotifyPropertyChanged(nameof(Name));
}
}
}
private string _name;
public int ItemCount
{
get { return _itemCount; }
set { _itemCount = value; NotifyPropertyChanged(nameof(ItemCount));
}
}
private int _itemCount;
}
}
The ObservableCollection class already contains handling of INotifyCollectionChanged.
You only need this line for the ObservableCollection. You can remove everything else that has to do with "InventoryItems" and the collection in your ViewModel.
public ObservableCollection<InventoryItem> InventoryItems { get; } = new ObservableCollection<InventoryItem>();
Also: When you add an item to the collection you need to create a new item. Otherwise you are adding the same object, that will not work.
This is my reduced ViewModel to how I think you want it to work:
public class ViewModel : ViewModelBase
{
private ICommand _addItem;
public string InputName
{
get { return _inputName; }
set
{
if (_inputName != value)
{
_inputName = value;
NotifyPropertyChanged(nameof(InputName));
}
}
}
private string _inputName;
public ObservableCollection<InventoryItem> InventoryItems { get; } = new ObservableCollection<InventoryItem>();
public ICommand AddItem
{
get
{
if (_addItem == null)
{
_addItem = new RelayCommand(ParamArrayAttribute => this.Submit(), null);
}
return _addItem;
}
}
private void Submit()
{
if (InventoryItems.Any(p => p.Name == InputName))
{
InventoryItems.First(x => x.Name == InputName).ItemCount++;
}
else
{
InventoryItems.Add(new InventoryItem() { Name = InputName, ItemCount = 1 });
}
}
}
To complete the picture, I have added following XAML for test:
<TextBox Text="{Binding InputName}" MinWidth="100" Margin="5"/>
<Button Content="Add" Command="{Binding AddItem}" Margin="5"/>

Update all parents when shared nested object gets updated

I have below class hierarchy.
public class RowViewModel : BaseViewModel
{
private CellViewModel cell;
public CellViewModel Cell
{
get { return cell; }
set
{
cell = value;
OnPropertyChanged("Cell");
}
}
}
public class CellViewModel : BaseViewModel
{
public string Text { get { return string.Join("\n", CellLinks.Select(c => c.Text)); } }
private ObservableCollection<CellLinkViewModel> cellLinks;
public ObservableCollection<CellLinkViewModel> CellLinks
{
get
{ return cellLinks; }
set
{
cellLinks = value;
OnPropertyChanged("CellLinks");
}
}
}
public class CellLinkViewModel : BaseViewModel
{
public string Text
{
get { return CellValue.Text; }
set
{
CellValue.Text = value;
OnPropertyChanged("Text");
}
}
public CellValueViewModel CellValue { get; set; }
}
public class CellValueViewModel : BaseViewModel
{
public string Text { get; set; }
}
public class BaseViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChangedEventArgs e = new PropertyChangedEventArgs(propertyName);
PropertyChanged(this, e);
}
}
}
XAML code looks like,
<DataGrid ItemsSource="{Binding Rows}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTemplateColumn Header="#" Width="200">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Cell.Text}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ListBox ItemsSource="{Binding Cell.CellLinks}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding Text, Mode=TwoWay}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
CellValueViewModel is shared across multiple CellLinkViewModel. When I change CellValueViewModel it should have propagated changes to all dependent parents and DataGrid should show all latest values.
This is result
But I think its not happening automatically, am I missing something here? How to notify all datagrid cells to update automatically when the nested objects gets updated.
You need to hook up event handlers to the PropertyChanged event for all CellLinkViewModel objects and raise the PropertyChanged event for the Text property of the CellViewModel whenever a link is modified, e.g.:
public class CellViewModel : BaseViewModel
{
public string Text { get { return string.Join("\n", CellLinks.Select(c => c.Text)); } }
private ObservableCollection<CellLinkViewModel> cellLinks;
public ObservableCollection<CellLinkViewModel> CellLinks
{
get
{
return cellLinks;
}
set
{
cellLinks = value;
if(cellLinks != null)
{
foreach(var link in cellLinks)
{
link.PropertyChanged += Link_PropertyChanged;
}
}
OnPropertyChanged("CellLinks");
}
}
private void Link_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
OnPropertyChanged("Text");
}
}
You probably also want to handle the CollectionChanged event for the ObservableCollection<CellLinkViewModel> and hook up event handlers to dynamically added CellLinkViewModel objects as well.

How do I pass all of the values in a gridrow in a wpf application?

I am trying to write a simple application where I display a listview using databinding containing multiple objects that lists their properties and a check box. I let the user check all of the boxes they want removed then press a button that removes the selected elements.
public partial class MainWindow : Window
{
ObservableCollection<User> Users = new ObservableCollection<User>();
public MainWindow()
{
System.Console.WriteLine("main window");
Users.Add(new User() { Name = "John Doe", Age = 42, Height = "6ft", Checked = false});
Users.Add(new User() { Name = "Jane Doe", Age = 39, Height = "6ft", Checked = false });
Users.Add(new User() { Name = "Sammy Doe", Age = 7, Height = "5ft", Checked = false });
drawFolderView();
}
private void drawFolderView()
{
InitializeComponent();
lvUsers.ItemsSource = Users;
}
private void button_Click(object sender, RoutedEventArgs e)
{
if (Users.Count > 0)
{
List<User> itemsToRemove = new List<User>();
foreach (User person in Users)
{
if (person.Checked)
{
itemsToRemove.Add(person);
}
}
foreach (User person in itemsToRemove)
{
Users.Remove(person);
}
}
else
{
System.Console.WriteLine("nothing in list");
}
drawFolderView();
}
private void CheckBox_Checked(object sender, RoutedEventArgs e)
{
}
private void CheckBox_Unchecked(object sender, RoutedEventArgs e)
{
}
}
public class User
{
public string Name { get; set; }
public int Age { get; set; }
public string Height { get; set; }
public bool Checked { get; set; }
public bool Equals(User other) {
if (Name.Equals(other.Name))
{
return true;
}
else
{
return false;
}
}
}
From reading the other questions I made the CheckBox_Checked and Unchecked methods, but I have no idea how to implement them.
Window x:Class="WpfApplication6.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication6"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<ListView Margin="10,10,10,98" Name="lvUsers">
<ListView.View>
<GridView>
<GridViewColumn Header="Name" Width="120" DisplayMemberBinding="{Binding Name}" />
<GridViewColumn Header="Age" Width="50" DisplayMemberBinding="{Binding Age}" />
<GridViewColumn Header="Height" Width="150" DisplayMemberBinding="{Binding Height}" />
<GridViewColumn Width="60">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox Margin="-4,0,-4,0" IsChecked="{Binding MyBoolProperty}" Checked="CheckBox_Checked" Unchecked="CheckBox_Unchecked" DataContext="{Binding Checked}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
<Button x:Name="button" Content="Delete" HorizontalAlignment="Left" Margin="353,243,0,0" VerticalAlignment="Top" Width="75" Click="button_Click" />
</Grid>
Is this a reasonable approach? Many of the concepts surrounding databinding in WPF still confuse me.
The Checkbox should be changed to this:
<CheckBox Margin="-4,0,-4,0" IsChecked="{Binding Checked}" />
The DataContext for the Checkbox is the User (like it is for the other columns). The IsChecked property of the Checkbox is bound to the Checked property on the User.
There is no need to call drawFolderView in the button_click method. The lvUsers.ItemsSource is already set to Users. Since Users is an ObservableCollection, it will raise events to tell WPF that items were removed/added and your listview will update itself automatically.
To work best with WPF, your User class should implement INotifyPropertyChanged. When the properties of User objects change, your bindings will get updated automatically. Right now, only the listview can change the User objects so you won't get any real benefit from INPC. But, if you added a button that looped through the Users and set User.Checked = true then you would need the INPC interface to tell WPF that the Checked property on the User objects changed so it could update the GUI.
Also, InitializeComponent() should be moved back to the top of the constructor. You only want that called when the window is being created.
Here is an updated version of your code with a few changes:
public partial class MainWindow : Window
{
ObservableCollection<User> Users = new ObservableCollection<User>();
public MainWindow()
{
InitializeComponent();
System.Console.WriteLine("main window");
Users.Add(new User() { Name = "John Doe", Age = 42, Height = "6ft", Checked = false });
Users.Add(new User() { Name = "Jane Doe", Age = 39, Height = "6ft", Checked = false });
Users.Add(new User() { Name = "Sammy Doe", Age = 7, Height = "5ft", Checked = false });
lvUsers.ItemsSource = Users;
}
private void button_Click(object sender, RoutedEventArgs e)
{
if (Users.Count > 0)
{
List<User> itemsToRemove = new List<User>();
foreach (User person in Users)
{
if (person.Checked)
{
itemsToRemove.Add(person);
}
}
foreach (User person in itemsToRemove)
{
Users.Remove(person);
}
}
else
{
System.Console.WriteLine("nothing in list");
}
}
}
public class User : System.ComponentModel.INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void OPC(string propertyName) // OPC = OnPropertyChanged; a helper that raises the PropertyChanged event
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
private string _name;
public string Name
{
get { return _name; }
set
{
if (_name != value)
{
_name = value;
OPC("Name");
}
}
}
private int _age;
public int Age { get { return _age; } set { if (_age != value) { _age = value; OPC("Age"); } } }
private string _height;
public string Height { get { return _height; } set { if (_height != value) { _height = value; OPC("Height"); } } }
private bool _checked;
public bool Checked { get { return _checked; } set { if (_checked != value) { _checked = value; OPC("Checked"); } } }
public bool Equals(User other)
{
if (Name.Equals(other.Name))
{
return true;
}
else
{
return false;
}
}
}

Update combobox while using DisplayMemberPath

I am using WPF and MVVM light framework (and I am new in using them)
Here is the situation:
I have a combobox displaying a list of items (loaded from a database) and I am using the DisplayMemberPath to display the title of the items in the combobox.
In the same GUI, the user can modify the item title in a text box. A button 'Save' allows the user to save the data into the database.
What I want to do is when the user clicks 'Save', the item title in the combobox gets updated too and the new value is displayed at that time. However, I do not know how to do that...
Some details on my implementation:
MainWindow.xaml
<ComboBox ItemsSource="{Binding SourceData}" SelectedItem="{Binding SelectedSourceData,Mode=TwoWay}" DisplayMemberPath="Title" />
<TextBlock Text="{Binding SelectedDataInTextFormat}"/>
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Closing += (s, e) => ViewModelLocator.Cleanup();
}
}
MainViewModel.xaml
public class MainViewModel:ViewModelBase
{
public ObservableCollection<Foo> SourceData{get;set;}
public Foo SelectedSourceData
{
get{return _selectedFoo;}
set{_selectedFoo=value; RaisePropertyChanged("SelectedSourceData"); }
}
public string SelectedDataInTextFormat
{
get{return _selectedDataInTextFormat;}
set{_selectedDataInTextFormat=value; RaisePropertyChanged("SelectedDataInTextFormat");
}
}
I would appreciate if anyone could help me on this one.
Thanks for your help.
Romain
You might simply update the SelectedSourceData property when SelectedDataInTextFormat changes:
public string SelectedDataInTextFormat
{
get { return _selectedDataInTextFormat; }
set
{
_selectedDataInTextFormat = value;
RaisePropertyChanged("SelectedDataInTextFormat");
SelectedSourceData = SourceData.FirstOrDefault(f => f.Title == _selectedDataInTextFormat)
}
}
EDIT: In order to change the Title property of the currently selected Foo item in the ComboBox, you could implement INotifyPropertyChanged in your Foo class:
public class Foo : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string title = string.Empty;
public string Title
{
get { return title; }
set
{
title = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("Title"));
}
}
}
}
Then simply set the Title property of the selected item:
SelectedSourceData.Title = SelectedDataInTextFormat;
There is many ways to do this, This example takes advantage of the Button Tag property to send some data to the save button handler(or ICommand), Then we can set the TextBox UpdateSourceTrigger to Explicit and call the update when the Button is clicked.
Example:
Xaml:
<Window x:Class="WpfApplication8.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="105" Width="156" Name="UI">
<Grid DataContext="{Binding ElementName=UI}">
<StackPanel Name="stackPanel1">
<ComboBox x:Name="combo" ItemsSource="{Binding SourceData}" DisplayMemberPath="Title" SelectedIndex="0"/>
<TextBox x:Name="txtbox" Text="{Binding ElementName=combo, Path=SelectedItem.Title, UpdateSourceTrigger=Explicit}"/>
<Button Content="Save" Tag="{Binding ElementName=txtbox}" Click="Button_Click"/>
</StackPanel>
</Grid>
</Window>
Code:
public partial class MainWindow : Window, INotifyPropertyChanged
{
private ObservableCollection<Foo> _sourceData = new ObservableCollection<Foo>();
public MainWindow()
{
InitializeComponent();
SourceData.Add(new Foo { Title = "Stack" });
SourceData.Add(new Foo { Title = "Overflow" });
}
public ObservableCollection<Foo> SourceData
{
get { return _sourceData; }
set { _sourceData = value; }
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var txtbx = (sender as Button).Tag as TextBox;
txtbx.GetBindingExpression(TextBox.TextProperty).UpdateSource();
}
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}
public class Foo : INotifyPropertyChanged
{
private string _title;
public string Title
{
get { return _title; }
set { _title = value; RaisePropertyChanged("Title"); }
}
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}
Code:
public ObservableCollection<Foo> SourceData{get;set;}
public Foo SelectedSourceData
{
get{
return _selectedFoo;
}
set{
_selectedFoo=value;
RaisePropertyChanged("SelectedSourceData");
}
}
public string SelectedDataInTextFormat //Bind the text to the SelectedItem title
{
get{
return SelectedSourceData.Title
}
set{
SelectedSourceData.Title=value;
RaisePropertyChanged("SelectedDataInTextFormat");
}
}
XAML:
<ComboBox ItemsSource="{Binding SourceData, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
SelectedItem="{Binding SelectedSourceData,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" DisplayMemberPath="Title" />
<TextBlock Text="{Binding SelectedDataInTextFormat, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>

Resources