Hi i need to make a program where you have to add an undefined number of elements to a list by choosing them from a combobox. I planned to use 4 basic comboboxes and when the user choose an element from the last one, the program should automatically add another one under the last one (i want to use a stackpanel).
How could i do?
Thanks.
My XAML:
<StackPanel Name="listPanel" Grid.Column="0" Margin="10">
<Label Content="Example" FontWeight="Bold" HorizontalAlignment="Center"/>
<ComboBox Name="ex1Combobox" Margin="0,10,0,0"
ItemsSource="{Binding ExList, Mode=TwoWay}"
SelectedValue="{Binding SelectedEx}"
DisplayMemberPath="Name"
SelectedValuePath="ID"/>
<ComboBox Name="ex2Combobox" Margin="0,10,0,0"
ItemsSource="{Binding ExList, Mode=TwoWay}"
SelectedValue="{Binding SelectedEx}"
DisplayMemberPath="Name"
SelectedValuePath="ID"/>
<ComboBox Name="ex3Combobox" Margin="0,10,0,0"
ItemsSource="{Binding ExList, Mode=TwoWay}"
SelectedValue="{Binding SelectedEx}"
DisplayMemberPath="Name"
SelectedValuePath="ID"/>
</StackPanel>
This is a pretty good example of why you should use MVVM.
Model
Has a collection of selected values only something like
public class MyChoices
{
public IEnumerable<string> Selections {get; set;}
}
ViewModel
Has a collection that extends as soon as you modify the last item
public class MyChoicesViewModel
{
public MyChoicesViewModel()
{
Selections = new ObservableCollection<ChoiceViewModel>();
//Add first empty value
AddNewItem();
Selections.CollectionChanged += (sender, e) =>
{
// If you change the last add another
if (e.NewItems.Contains(Selections.Last()))
AddNewItem();
};
}
public ObservableCollection<ChoiceViewModel> Selections {get; private set;}
public void AddNewItem()
{
var newItem = new ChoiceViewModel();
Selections.Add(newItem);
newItem.PropertyChanged += () =>
{
//This is where we update the model from the ViewModel
Model.Selections = from x in Selections
select x.Value;
}
}
}
public class ChoiceViewModel : INotifyPropertyChanged
{
private string _chosen;
public string Chosen
{
get { return _chosen; }
set {
if (_chosen != value)
{
_chose = value;
OnPropertyChanged();
}
}
}
public void OnPropertyChanged([CallerMemberName] string property)
{
var temp = PropertyChanged;
if (temp != null)
{
temp(this, new PropertyChangedEventArgs(property));
}
}
}
}
View
<!-- Then show many of them-->
<ListBox ItemsSource="{Binding Selections}"/>
Related
I have an object that consists of a string and an array. The string populates a ComboBox and the array populates a ListView depending on the selected string value. Each line of the ListViewconsists of a TextBlock and a CheckBox.
On submit I want to be able to verify which items have been selected for further processing but there's a disconnect when using the MVVM approach. I currently have the DataContext of the submit Button binding to the ListView but only the first value is being returned upon submit (somewhere I need to save the selected values to a list I assume but I'm not sure where). I added an IsSelected property to the model which I think is the first step, but after that I've been grasping at straws.
Model
namespace DataBinding_WPF.Model
{
public class ExampleModel { }
public class Example : INotifyPropertyChanged
{
private string _name;
private string[] _ids;
private bool _isSelected;
public bool IsSelected
{
get => _isSelected;
set
{
if (_isSelected != value)
{
_isSelected = value;
RaisePropertyChanged("IsSelected");
}
}
}
public string Name
{
get => _name;
set
{
if (_name != value)
{
_name = value;
RaisePropertyChanged("Name");
}
}
}
public string[] IDs
{
get => _ids;
set
{
if (_ids != value)
{
_ids = value;
RaisePropertyChanged("IDs");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new
PropertyChangedEventArgs(property));
}
}
}
}
ViewModel
namespace DataBinding_WPF.ViewModel
{
public class ExampleViewModel : INotifyPropertyChanged
{
public ObservableCollection<Example> Examples
{
get;
set;
}
// SelectedItem in the ComboBox
// SelectedItem.Ids will be ItemsSource for the ListBox
private Example _selectedItem;
public Example SelectedItem
{
get => _selectedItem;
set
{
_selectedItem = value;
RaisePropertyChanged(nameof(SelectedItem));
}
}
// SelectedId in ListView
private string _selectedId;
public string SelectedId
{
get => _selectedId;
set
{
_selectedId = value;
RaisePropertyChanged(nameof(SelectedId));
}
}
private string _selectedCheckBox;
public string IsSelected
{
get => _selectedCheckBox;
set
{
_selectedCheckBox = value;
RaisePropertyChanged(nameof(IsSelected));
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new
PropertyChangedEventArgs(property));
}
}
public void LoadExample()
{
ObservableCollection<Example> examples = new ObservableCollection<Example>();
examples.Add(new Example { Name = "Mark", IDs = new string[] { "123", "456" }, IsSelected = false });
examples.Add(new Example { Name = "Sally", IDs = new string[] { "789", "101112" }, IsSelected = false });
Examples = examples;
}
/* BELOW IS A SNIPPET I ADDED FROM AN EXAMPLE I FOUND ONLINE BUT NOT SURE IF IT'S NEEDED */
private ObservableCollection<Example> _bindCheckBox;
public ObservableCollection<Example> BindingCheckBox
{
get => _bindCheckBox;
set
{
_bindCheckBox = value;
RaisePropertyChanged("BindingCheckBox");
}
}
}
}
View
<UserControl x:Class = "DataBinding_WPF.Views.StudentView"
xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d = "http://schemas.microsoft.com/expression/blend/2008"
xmlns:local = "clr-namespace:DataBinding_WPF"
mc:Ignorable = "d"
d:DesignHeight = "300" d:DesignWidth = "300">
<Grid>
<StackPanel HorizontalAlignment = "Left" >
<ComboBox HorizontalAlignment="Left"
VerticalAlignment="Top"
Width="120"
ItemsSource="{Binding Path=Examples}"
SelectedItem="{Binding SelectedItem}"
DisplayMemberPath="Name"/>
<ListView x:Name="myListView"
ItemsSource="{Binding SelectedItem.IDs}"
DataContext="{Binding DataContext, ElementName=submit_btn}"
SelectedItem="{Binding SelectedId}"
Height="200" Margin="10,50,0,0"
Width="Auto"
VerticalAlignment="Top"
Background="AliceBlue">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<CheckBox
Name="myCheckBox"
IsChecked="{Binding IsSelected,
RelativeSource={RelativeSource AncestorType=ListViewItem}}"
Margin="5, 0"/>
<TextBlock Text="{Binding}" FontWeight="Bold" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Button HorizontalAlignment="Left" Height="20" Width="100"
Click="Submit" x:Name="submit_btn">Submit</Button>
</StackPanel>
</Grid>
</UserControl>
View.cs
namespace DataBinding_WPF.Views
{
/// <summary>
/// Interaction logic for StudentView.xaml
/// </summary>
public partial class StudentView : UserControl
{
public StudentView()
{
InitializeComponent();
}
private void Submit(object sender, EventArgs e)
{
var selectedItems = ((Button)sender).DataContext;
// process each selected item
// foreach (var selected in ....) { }
}
}
}
The ListView control already exposes a selected items collection as property SelectedItems.
private void Submit(object sender, RoutedEventArgs e)
{
var selectedIds = myListView.SelectedItems.Cast<string>().ToList();
// ...do something with the items.
}
However, I doubt that you want to do this in the code-behind, but rather in the view model. For this purpose, WPF offers the concept of commands.
MVVM - Commands, RelayCommands and EventToCommand
What you need is a relay command or delegate command (the name varies across frameworks). It encapsulates a method that should be executed for e.g. a button click and a method to determine whether the command can be executed as an object that can be bound in the view. Unfortunately, WPF does not provide an implementation out-of-the-box, so you either have to copy an implementation like here or use an MVVM framework that already provides one, e.g. Microsoft MVVM Tookit.
You would expose a property Submit of type ICommand in your ExampleViewModel and initialize it in the constructor with an instance of RelayCommand<T> that delegates to a method to execute.
public class ExampleViewModel : INotifyPropertyChanged
{
public ExampleViewModel()
{
Submit = new RelayCommand<IList>(ExecuteSubmit);
}
public RelayCommand<IList> Submit { get; }
// ...other code.
private void ExecuteSubmit(IList selectedItems)
{
// ...do something with the items.
var selectedIds = selectedItems.Cast<string>().ToList();
return;
}
}
In your view, you would remove the Click event handler and bind the Submit property to the Command property of the Button. You can also bind the SelectedItems property of the ListView to the CommandParameter property, so the selected items are passed to the command on execution.
<Button HorizontalAlignment="Left"
Height="20"
Width="100"
x:Name="submit_btn"
Command="{Binding Submit}"
CommandParameter="{Binding SelectedItems, ElementName=myListView}">Submit</Button>
Additionally, a few remarks about your XAML.
Names of controls in XAML should be Pascal-Case, starting with a capital letter.
You should remove the DataContext binding from ListView completely, as it automatically receives the same data context as the Button anyway.
DataContext="{Binding DataContext, ElementName=submit_btn}"
You can save yourself from exposing and binding the SelectedItem property in your ExampleViewModel, by using Master/Detail pattern for hierarchical data.
<Grid>
<StackPanel HorizontalAlignment = "Left" >
<ComboBox HorizontalAlignment="Left"
VerticalAlignment="Top"
Width="120"
ItemsSource="{Binding Path=Examples}"
IsSynchronizedWithCurrentItem="True"
DisplayMemberPath="Name"/>
<ListView ItemsSource="{Binding Examples/IDs}"
SelectedItem="{Binding SelectedId}"
Height="200" Margin="10,50,0,0"
Width="Auto"
VerticalAlignment="Top"
Background="AliceBlue">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<CheckBox Name="myCheckBox"
IsChecked="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=ListViewItem}}"
Margin="5, 0"/>
<TextBlock Text="{Binding}"
FontWeight="Bold" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Button HorizontalAlignment="Left"
Height="20"
Width="100"
Command="{Binding Submit}"
CommandParameter="{Binding SelectedItems, ElementName=myListView}">Submit</Button>
</StackPanel>
</Grid>
If the view's data context is bound to the view then remove the DataContext from the ListView.
You could remove the item template and instead use a GridView like:
<ListView.View>
<GridView >
<GridViewColumn Header="Selected" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsSelected}" Content="{Binding Name}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
Since the ItemSource is an Observable collection, there are several options to monitor changes in the checkboxes:
Add an event handler to the item changed event of the collection and then you can add the Name or the collection index to a local collection. e.g Examples[e.CollectionIndex].Name
Alternatively iterate over the observable collection and select those Examples where Selected = "true"
I'm making a ListView filled with List of objects, which properties are shown and editable in a ListView. I need to get object when its properties are being updated. How can I do this?
I tried creating an object of class and bind it to SelectedItem in ListView. The problem is that, obviously, the SelectedItem is set after clicking the row of ListItem, but not the children of that row. I need to get the updated object from the row of my ListView each time after any ComboBox or TextBox values are changed.
To handle all the things with INotifyPropertyChanged I'm using PropertyChanged.Fody. Could it help me to solve this problem easier?
View
Appearance of the ListView
<ListView
Margin="10"
Grid.Row="1"
Grid.ColumnSpan="2"
ItemsSource="{Binding TimesheetEntries}"
SelectedItem="{Binding SelectedEntry, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Height="30" Margin="3">
<TextBlock
Text="{Binding Date, StringFormat=dd-MM-yyyy}"
VerticalAlignment="Center"
Width="Auto"
Margin="10"/>
<ComboBox
SelectedValuePath="Key" DisplayMemberPath="Value"
ItemsSource="{Binding EmploymentTypesDictionary, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
SelectedValue="{Binding SelectedEmployment, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Width="270"/>
<TextBox
Text="{Binding Hours, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Margin="10,0,0,0"
Width="70"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
ViewModel
public List<TimesheetEntryEntity> TimesheetEntries
{
get { return _TimesheetEntries; }
set { _TimesheetEntries = value; }
}
public TimesheetEntryEntity SelectedEntry
{
get { return _SelectedEntry; }
set { _SelectedEntry = value; }
}
...
private List<TimesheetEntryEntity> _TimesheetEntries { get; set; }
private TimesheetEntryEntity _SelectedEntry;
private TimesheetModel timesheetModel;
public TimesheetViewModel()
{
this.Timesheets = TimesheetUnitModel.GetAllTimesheetsForUnit((int)Application.Current.Properties["UnitID"]);
this._StartDate = DateTime.Now;
_TimesheetEntries = new List<TimesheetEntryEntity>();
}
public KeyValuePair<int, string> SelectedWorker
{
get { return _SelectedWorker; }
set
{
_SelectedWorker = value;
_TimesheetEntries =
timesheetModel.GetTimesheetList(_SelectedWorker.Key, SelectedTimesheet.Key, StartDate.Date);
}
}
TimesheetEntryEntity
public DateTime Date { get; set; }
public Dictionary<EmploymentTypes, string> EmploymentTypesDictionary { get; set; }
public EmploymentTypes SelectedEmployment {
get { return _SelectedEmployment; }
set
{
_SelectedEmployment = value;
CheckHoursAvaliability();
}
}
public bool HoursAvaliable { get; set; }
public decimal Hours
{
get;
set;
}
private EmploymentTypes _SelectedEmployment;
public TimesheetEntryEntity()
{
FillEmploymentTypes();
}
public void FillEmploymentTypes()
{
//Some code here
}
I tried to follow the answer from Get Object properties of selected list item question, but there were only textblocks, so the row gets selected anyway, but i have ComboBox and TextBox, who get their own focus.
You can implement INotifyPropertyChanged in your TimesheetEntryEntity i.e.
public abstract class TimesheetEntryEntity: INotifyPropertyChanged
{
public event EventHandler Changed;
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public void OnChange()
{
EventHandler handler = Changed;
handler?.Invoke(this, EventArgs.Empty);
}
private DateTime date;
public DateTime Date
{
get => date;
set
{
if (date == value)
{
return;
}
//Do something with unchanged property
date = value;
RaisePropertyChanged();
OnChange();
//Do something with changed property
}
}
in your ViewModel before adding new item to list:
timesheet.Changed+=ItemChanged;
and
private void ItemChanged(object sender, EventArgs e)
{
var item=sender as TimesheetEntryEntity;
//do something
}
I'm working on a small WPF project,
for now it contains one window which should display as much checkboxes are many values in lists are.
For testing purposes, before I get values from database I tried something like this:
public class StatusOption
{
public string name { get; set; }
public bool IsSelected { get; set; }
}
public void GetSerialNumbers()
{
List<StatusOption> serialNumbers = new List<StatusOption>();
for(int i = 0; i<10;i++)
{
StatusOption x = new StatusOption();
x.name = "Random name" + i;
x.IsSelected = false;
serialNumbers.Add(x);
}
}
And my xaml looks like this:
<ListBox x:Name="SerialNumbersListBox"
AllowDrop="True"
Grid.ColumnSpan="2"
Grid.Row="2"
ItemsSource="{Binding GetSerialNumbers}">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding serialNumbers}"
IsChecked="{Binding IsSelected}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
But unfortunatelly nothing is displayed below textbox...
But for now everything is empty, and I can not find out why..
Thanks guys
Cheers
You could not bind a method. Please use property instead.
<ListBox HorizontalAlignment="Left" Height="171" Margin="334,96,0,0" VerticalAlignment="Top" Width="248" AllowDrop="True" x:Name="SerialNumbersListBox"
ItemsSource="{Binding SerialNumbers}">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding name}"
IsChecked="{Binding IsSelected}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
public class SerialNumbersListBoxViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public class StatusOption
{
public string name { get; set; }
public bool IsSelected { get; set; }
}
private ObservableCollection<StatusOption> _SerialNumbers;
public ObservableCollection<StatusOption> SerialNumbers
{
get
{
return _SerialNumbers;
}
set
{
if (value != _SerialNumbers)
{
_SerialNumbers = value;
OnPropertyChanged(nameof(SerialNumbers));
}
}
}
public void GetSerialNumbers()
{
if (_SerialNumbers == null)
_SerialNumbers = new ObservableCollection<StatusOption>();
for (int i = 0; i < 10; i++)
{
StatusOption x = new StatusOption();
x.name = "Random name" + i;
x.IsSelected = false;
_SerialNumbers.Add(x);
}
}
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public SerialNumbersListBoxViewModel()
{
GetSerialNumbers();
}
}
You can refer this link for more details
Regard!
You cannot bind to methods, you can only bind to Properties or DependencyProperties.
So you need to create a Property for your serialNumbers. You should also implement INotifyPropertyChanged, so that the ListBox can know when your property changed.
public List<object> SerialNumbers
{
get => this._serialNumbersProperty;
set
{
if (!List<object>.Equals(value, this._serialNumbersProperty))
{
this._serialNumbersProperty = value;
OnPropertyChanged(nameof(this.SerialNumbers));
}
}
}
<ListBox x:Name="SerialNumbersListBox"
AllowDrop="True"
Grid.ColumnSpan="2"
Grid.Row="2"
ItemsSource="{Binding SerialNumbers}">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding name}"
IsChecked="{Binding IsSelected}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I'm not understanding why my combo box doesn't update when I make a selection in another combobox. I'm still new to MVVM but in theory my code should work. I can populate the combos when the form loads but i need to refresh the combo with new values, and that's not working. I can see it retrieving new values but it never displays them on the form.
My XAML looks like this:
<ComboBox Grid.Column="1" ItemsSource="{Binding Path=Vendors}" SelectedItem="{Binding SelectedVendor, Mode=TwoWay}" HorizontalAlignment="Left" Margin="24,12,0,11" Grid.Row="3" VerticalAlignment="Center" Width="293" />
<ComboBox x:Name="VendorProductServiceCB" HorizontalAlignment="Left" Margin="20.6,16.2,0,55.4" VerticalAlignment="Center" Width="293" Grid.Row="7" Grid.Column="1" ItemsSource="{Binding Path=VendorProductServices, UpdateSourceTrigger=PropertyChanged}" DisplayMemberPath="Name" SelectedItem="{Binding Path=SelectedVendorProductService, Mode=TwoWay}" Height="22"/>
My ViewModel code is this:
public ObservableCollection<string> Vendors { get; set; }
public ObservableCollection<VendorProductService> VendorProductServices { get; private set; }
public VendorProductService SelectedVendorProductService
{
get { return _selectedVendorProductService; }
set { SetProperty(ref _selectedVendorProductService, value); }
}
public string SelectedVendor
{
get { return _selectedVendor; }
set
{
SetProperty(ref _selectedVendor, value);
SelectionChangedCommand.Execute(this);
}
}
public FormSelectionViewModel()
{
Vendors = new ObservableCollection<string>(FetchVendors());
VendorProductServices = new ObservableCollection<VendorProductService>(FetchVendorProductServices(_selectedVendor));
SelectionChangedCommand = new DelegateCommand(SelectionChanged);
}
public void SelectionChanged()
{
VendorProductServices = new ObservableCollection<VendorProductService>(FetchVendorProductServices(_selectedVendor));
}
You're not raising the PropertyChanged event for the VendorProductServices, because it's an auto property.
Either change it to:
private ObservableCollection<VendorProductService> _vendorProductServices;
public ObservableCollection<VendorProductService> VendorProductServices
{
get { return _vendorProductServices; }
private set { SetProperty(ref _vendorProductServices, value); }
}
Or change your collection properties to read only and use .Clear() and .Add() instead of creating new collections.
I have a problem in c# wpf tring to bind to CurrentItem, i have a list of persons, and each persons can have one of two items. You can select a person in the list and then select it's item in a combobox.
The combobox binds to Persons.CurrentItem.Item and shows what the person have as selected item. But i cant change it, or rather i cant keep the change that is made, it changes back as soon as i select a new person.
The XAML looks like this:
<!--This dose not work-->
<TextBox Height="23" HorizontalAlignment="Left" Margin="148,55,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" Text="{Binding Path=Persons.CurrentItem.Item.Name}"/>
<!--This works-->
<TextBox Height="23" HorizontalAlignment="Left" Margin="16,306,0,0" Name="textBox2" VerticalAlignment="Top" Width="120" Text="{Binding Path=Persons.CurrentItem.Name}"/>
<!--This works, we do not bind to CurrentItem-->
<ListBox Height="274" HorizontalAlignment="Left" ItemsSource="{Binding Path=Persons2}" SelectedItem="{Binding Path=SelectedPerson}" Margin="292,26,0,0" Name="listBox2" VerticalAlignment="Top" Width="120" DisplayMemberPath="Name" />
<ComboBox Height="23" HorizontalAlignment="Left" ItemsSource="{Binding Path=Items}" SelectedItem="{Binding Path=SelectedPerson.Item}" Margin="431,26,0,0" Name="comboBox2" VerticalAlignment="Top" Width="120" DisplayMemberPath="Name"/>
</Grid>
As you can see i have added a persons2 with SelectedItem as SelectedPerson. This works fine and i want to mimic it's function but i want to use Current item.
This is the C# code:
// Selectable items
public List<Item> Items { get; set; }
// List of persons, we will bind to it's CurrentItem
public List<Person> Persons { get; set; }
// This works, we do not use CurrentItem
public List<Person> Persons2 { get; set; }
private Person _selectedPerson;
public Person SelectedPerson
{
get { return _selectedPerson; }
set
{
_selectedPerson = value;
NotifyPropertyChanged("SelectedPerson");
}
}
#region Constructo
public Window()
{
InitializeComponent();
DataContext = this;
// Populate Items
Items = new List<Item>
{
new Item {Name = "Hammer"},
new Item {Name = "Axe"}
};
// Populate persons
Persons = new List<Person>() { new Person { Name = "Lisa", Item = Items.FirstOrDefault()}, new Person { Name = "Kauf" } };
Persons2 = new List<Person>(Persons); // make a copy
}
#endregion
#region PropertyChangeHandler
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(string name)
{
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(name));
}
#endregion
}
public class Item
{
public string Name { get; set; }
}
public class Person
{
public string Name { get; set; }
private Item _item;
public Item Item
{
get { return _item; }
set
{
// We only accass this if we do not bind to CurrentItem
_item = value;
}
}
}
If you test the example you can see that Persons.CurrentItem.Name works, but Persons.CurrentItem.Item.Name dose not, Why? Have i missed something with the level of access?
Is there something i have missed on how to use CurrentItem?
Thanks for enlightening me.
Asked the same question on msdn:
http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/18eee956-3a91-4db3-a4ff-7e8d127ae301
The solution is not use CurentItem but instead / like this:
<StackPanel>
<ListBox ItemsSource="{Binding Path=Persons}" IsSynchronizedWithCurrentItem="True" DisplayMemberPath="Name" />
<ComboBox HorizontalAlignment="Left" VerticalAlignment="Top" ItemsSource="{Binding Path=Items}" SelectedItem="{Binding Persons/Item}" DisplayMemberPath="Name"/>
</StackPanel>