What I'm trying to do is create a UserControl to which I can pass an Address object. It seems that when I pass Address="{Binding Path=Person.Address}" to the UserControl, the embedded TextBox is binding to Text="{Binding Path=Person.Address}" instead of Text="{Binding Path=Address.Summary}"
Am I going about this all wrong?
Here's a link to the project if you want to play with it: http://dl.dropbox.com/u/4220513/WpfApplication2.zip
Domain objects:
namespace WpfApplication2
{
public class Person
{
public String Name { get; set; }
public Address Address { get; set; }
}
public class Address
{
public String Street { get; set; }
public String City { get; set; }
public String Summary { get { return String.Format("{0}, {1}", Street, City); } }
}
}
MainWindow:
namespace WpfApplication2
{
public partial class MainWindow : Window
{
private readonly ViewModel vm;
public MainWindow()
{
InitializeComponent();
vm = new ViewModel();
DataContext = vm;
vm.Person = new Person()
{
Name = "Bob",
Address = new Address()
{
Street = "123 Main Street",
City = "Toronto",
},
};
}
}
public class ViewModel : INotifyPropertyChanged
{
private Person person;
public Person Person { get { return person; } set { person = value; NotifyPropertyChanged("Person"); } }
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(String propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication2"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<TextBlock Text="Name:" />
<TextBlock Text="{Binding Path=Person.Name}" />
<TextBlock Text="Address:" />
<local:AddressView Address="{Binding Path=Person.Address}" />
</StackPanel>
</Window>
UserControl:
namespace WpfApplication2
{
public partial class AddressView : UserControl
{
public AddressView()
{
InitializeComponent();
DataContext = this;
}
public Address Address
{
get { return (Address)GetValue(AddressProperty); }
set { SetValue(AddressProperty, value); }
}
public static readonly DependencyProperty AddressProperty =
DependencyProperty.Register("Address", typeof(Address), typeof(AddressView));
}
}
<UserControl x:Class="WpfApplication2.AddressView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<TextBox Text="{Binding Path=Address.Summary}" IsReadOnly="True" />
</UserControl>
Error:
System.Windows.Data Error: 40 : BindingExpression path error: 'Person' property not found on 'object' ''AddressView' (Name='')'. BindingExpression:Path=Person.Address; DataItem='AddressView' (Name=''); target element is 'AddressView' (Name=''); target property is 'Address' (type 'Address')
In MainWindow.xaml :
<local:AddressView DataContext="{Binding Path=Person.Address}" />
and then in AddressView.xaml
<TextBox Text="{Binding Path=Summary, Mode=OneWay}" IsReadOnly="True" />
This displays the summary for me.
Related
I am creating a WPF application. This application contains a model, a view and a viewmodel that are the following.
Model:
public class PersonModel
{
public string Name { get; set; }
public int Age { get; set; }
public PersonModel(string name, int age)
{
Name = name;
Age = age;
}
}
ViewModel:
public class PersonViewModel : BaseViewModel
{
private readonly PersonModel _person;
public PersonViewModel(PersonModel person)
{
_person = person;
}
public string Name
{
get => _person.Name;
set
{
_person.Name = value;
OnPropertyChanged();
}
}
public int Age
{
get => _person.Age;
set
{
_person.Age = value;
OnPropertyChanged();
}
}
}
View:
<Window x:Class="testMvvM.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:testMvvM"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<StackPanel>
<TextBlock Text="{Binding Path=Name}" Height="50"/>
<Label Content="{Binding Path=Age}" Height="50"/>
</StackPanel>
</Window>
CODE BEHIND
public partial class MainWindow : Window
{
private PersonModel person = new PersonModel("Hola", 12);
private PersonViewModel personViewModel;
public MainWindow()
{
InitializeComponent();
personViewModel = new PersonViewModel(person);
DataContext = personViewModel;
_ = ChangePersonAsync();
}
private async Task ChangePersonAsync()
{
await Task.Delay(5000);
person.Age = 30;
await Task.Delay(5000);
personViewModel.Age = 50;
}
}
I would like to ensure that changing the value of the name or age property in the model propagates the change to the View.
If I change the property in the ViewModel, the change does propagate to the model and the View, but if I change them in the model, the get call of the ViewModel does not come and it does not come displayed in the View
sorry for my English
Goal
My actual goal is to navigate the ContentPresenter not by the main navigation, but via a button within the navigated page.
My current results
This is my Main navigation on the left hand side:
When clicked on either of the main navigation items, the ContentPresenter will load it's ViewModel.
Here is the Home tab
and the Some Other tab
Expected results
My expectation is to click on the button (See image below) from the loaded View Model, and navigate to the other view model...
But I am not sure how to implement such idea.
Code
Page View Model
public class PageViewModel
{
public string Title { get; set; }
public object Content { get; set; }
public List<PageViewModel> Children { get; set; }
}
Main View Model
public class MainViewModel
{
public List<PageViewModel> Navigation { get; set; }
public MainViewModel()
{
Navigation = new List<PageViewModel>
{
new PageViewModel
{
Title = "Home",
Content = new HomeViewModel()
},
new PageViewModel
{
Title = "Some Other Tab",
Content = new SomeOtherViewModel()
}
};
}
}
MainWindow.xaml
...
<Window.DataContext>
<local:MainViewModel />
</Window.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<StackPanel>
<ListView ItemsSource="{Binding Navigation}"
x:Name="Nav">
<ListView.ItemTemplate>
<DataTemplate DataType="{x:Type local:PageViewModel}">
<TextBlock Text="{Binding Title}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
<ContentPresenter Content="{Binding ElementName=Nav, Path=SelectedItem.Content}"
Grid.Column="1"/>
</Grid>
</Window>
Home View Model
public class HomeViewModel
{
public string SomeTitle { get; set; }
public HomeViewModel()
{
SomeTitle = "Hello Home ViewModel";
}
}
Some Other View Model
public class SomeOtherViewModel
{
public string SomeTitle { get; set; }
public SomeOtherViewModel()
{
SomeTitle = "Hello SomeOther View Model";
}
}
Question
What would be the correct implementation to navigate via the internal (child) view model?
You must implement INotifyPropertyChanged in the MainViewModel and add a property called SelectedItem to bind to the listview.
I put the code to do this below. The code works properly.
PageViewModel.cs
public class PageViewModel
{
public string Title { get; set; }
public object Content { get; set; }
}
MainViewModel.cs
public class MainViewModel : INotifyPropertyChanged
{
public List<PageViewModel> Navigation { get; set; }
private PageViewModel selectedItem { get; set; }
public PageViewModel SelectedItem
{
get { return selectedItem; }
set
{
selectedItem = value;
OnPropertyChanged("SelectedItem");
}
}
public MainViewModel()
{
Navigation = new List<PageViewModel>
{
new PageViewModel
{
Title = "Home",
Content = new HomeViewModel(this),
},
new PageViewModel
{
Title = "Some Other Tab",
Content = new SomeOtherViewModel(),
}
};
SelectedItem = Navigation.FirstOrDefault();
}
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
HomeViewModel.cs
public class HomeViewModel
{
public string SomeTitle { get; set; }
public object View { get; set; }
MainViewModel mainViewModel;
public RelayCommand SomeOtherCommand { get; private set; }
public HomeViewModel(MainViewModel _mainViewModel)
{
SomeTitle = "Hello Home ViewModel";
View = new View1(this);
mainViewModel = _mainViewModel;
SomeOtherCommand = new RelayCommand(SomeOtherMethod);
}
private void SomeOtherMethod(object parameter)
{
mainViewModel.SelectedItem = mainViewModel.Navigation.Where(a => a.Title == "Some Other Tab").FirstOrDefault();
}
}
SomeOtherViewModel.cs
public class SomeOtherViewModel
{
public string SomeTitle { get; set; }
public object View { get; set; }
public SomeOtherViewModel()
{
SomeTitle = "Hello SomeOther View Model";
View = new View2();
}
}
RelayCommand.cs
public class RelayCommand : ICommand
{
readonly Action<object> _execute;
readonly Predicate<object> _canExecute;
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
{
throw new NullReferenceException("execute");
}
else
{
_execute = execute;
_canExecute = canExecute;
}
}
public event EventHandler CanExecuteChanged;
public void RaiseCanExecuteChanged()
{
if (CanExecuteChanged != null)
CanExecuteChanged(this, EventArgs.Empty);
}
public RelayCommand(Action<object> execute) : this(execute, null)
{
}
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
public void Execute(object parameter)
{
_execute.Invoke(parameter);
}
}
MainWindow.xaml
<Window.DataContext>
<local:MainViewModel />
</Window.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<StackPanel>
<ListView ItemsSource="{Binding Navigation}" x:Name="Nav" SelectedItem="{Binding Path=SelectedItem,Mode=TwoWay}">
<ListView.ItemTemplate>
<DataTemplate DataType="{x:Type local:PageViewModel}">
<TextBlock Text="{Binding Title}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
<ContentPresenter Content="{Binding ElementName=Nav, Path=SelectedItem.Content.View}" Grid.Column="1" />
</Grid>
View1.xaml
<Grid>
<Button x:Name="btnGet" Content="get" Height="40" Command="{Binding SomeOtherCommand}"></Button>
</Grid>
View2.xaml
<Grid>
<Button Content="test"></Button>
</Grid>
View1.cs
public partial class View1 : UserControl
{
public View1(HomeViewModel homeViewModel)
{
InitializeComponent();
DataContext = homeViewModel;
}
}
My question has two parts:
Label content is not updating when using Content="{Binding SelectedPerson.Age}" in xaml instead of
SelectedPersonAge.Content = SelectedPerson.Age; refering to Why binding using ItemsSource is working in code but not in xaml?. I have set the datacontext and SelectedPerson is a property.
Even when updating upon combobox item changed (using code behind), when a modification occurs on one of the properties of the selected item label field is not updating, I tried to implement INotifyPropertyChanged but it fires when .add() .delete() .clear() are involved but does not with Peoplelist[0].Age = 5;.
What I am doing wrong? Is it possible to achieve by simple code without using complicated mvvm external frameworks?
Mainwindow.xaml.cs
using System;
using System.Collections.ObjectModel;
using System.Windows;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace WpfTest
{
public partial class MainWindow : Window, INotifyPropertyChanged
{
public ObservableCollection<People> Peoplelist { get; set; } = new ObservableCollection<People>();
public event PropertyChangedEventHandler PropertyChanged;
private People _SelectedPerson;
public People SelectedPerson
{
get { return _SelectedPerson; }
set
{
if (value != _SelectedPerson)
{
_SelectedPerson= value;
NotifyPropertyChanged("SelectedPerson");
}
}
}
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public MainWindow()
{
People.Populate(Peoplelist);
InitializeComponent();
DataContext = this;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
//Modify Jon's Age property while it's selected: not automatically updating in ui
Peoplelist[0].Age = 5;
}
private void combo1_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
SelectedPersonAge.Content = SelectedPerson.Age; //not working when put in xaml
}
}
public class People : INotifyPropertyChanged
{
public string FirstName { get; set; }
public string LastName { get; set; }
private int _Age;
public int Age
{
get { return _Age; }
set
{
_Age = value;
RaisePropertyChanged("Age");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public People() { }
public People(String _FirstName, String _FamilyName)
{
FirstName = _FirstName;
LastName = _FamilyName;
Age = 0;
}
public static void Populate(ObservableCollection<People> lst)
{
lst.Add(new People
{
FirstName = "Jon",
LastName = "Jonathan",
});
lst.Add(new People
{
FirstName = "Mark",
LastName = "Markthan",
});
lst.Add(new People
{
FirstName = "Spence",
LastName = "Spencer",
});
}
}
}
MainWindow.xaml
<Window x:Class="WpfTest.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"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<StackPanel>
<ComboBox Name="combo1" VerticalAlignment="Center" HorizontalAlignment="Center" MinWidth="200" SelectedValuePath="Age" SelectionChanged="combo1_SelectionChanged" ItemsSource="{Binding Path=Peoplelist}" SelectedItem="{Binding SelectedPerson}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding FirstName}"/>
<TextBlock Text="--"/>
<TextBlock Text="{Binding LastName}"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<Label Name="SelectedPersonAge" Width="200" Height="35" HorizontalAlignment="center" VerticalAlignment="center" Content="{Binding SelectedPerson.Age}"/>
<Button Height="35" Click="Button_Click">
Test
</Button>
</StackPanel>
</Grid>
</Window>
As #PeterDuniho pointed out in his comment I corrected the DataContext for both controls combobox and label using DataContext="{Binding ElementName=MyWindow}.
SelectedPersonAge.Content = combo1.SelectedValue; is not required anymore as it is implemented in xaml.
Mainwindow.xaml.cs
using System;
using System.Collections.ObjectModel;
using System.Windows;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace WpfTest
{
public partial class MainWindow : Window, INotifyPropertyChanged
{
public ObservableCollection<People> Peoplelist { get; set; } = new ObservableCollection<People>();
public event PropertyChangedEventHandler PropertyChanged;
private People _SelectedPerson;
public People SelectedPerson
{
get { return _SelectedPerson; }
set
{
if (value != _SelectedPerson)
{
_SelectedPerson= value;
NotifyPropertyChanged("SelectedPerson");
}
}
}
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public MainWindow()
{
People.Populate(Peoplelist);
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
//Modify Jon's Age property while it's selected: not automatically updating in ui
Peoplelist[0].Age = 5;
}
private void combo1_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
}
}
public class People : INotifyPropertyChanged
{
public string FirstName { get; set; }
public string LastName { get; set; }
private int _Age;
public int Age
{
get { return _Age; }
set
{
_Age = value;
RaisePropertyChanged("Age");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public People() { }
public People(String _FirstName, String _FamilyName)
{
FirstName = _FirstName;
LastName = _FamilyName;
Age = 0;
}
public static void Populate(ObservableCollection<People> lst)
{
lst.Add(new People
{
FirstName = "Jon",
LastName = "Jonathan",
});
lst.Add(new People
{
FirstName = "Mark",
LastName = "Markthan",
});
lst.Add(new People
{
FirstName = "Spence",
LastName = "Spencer",
});
}
}
}
MainWindow.xaml
<Window x:Class="WpfTest.MainWindow" x:Name="MyWindow"
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"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<StackPanel>
<ComboBox Name="combo1" VerticalAlignment="Center" HorizontalAlignment="Center" MinWidth="200" SelectedValuePath="Age" SelectionChanged="combo1_SelectionChanged" ItemsSource="{Binding Path=Peoplelist}" SelectedItem="{Binding SelectedPerson}" DataContext="{Binding ElementName=MyWindow}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding FirstName}"/>
<TextBlock Text="--"/>
<TextBlock Text="{Binding LastName}"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<Label Name="SelectedPersonAge" Width="200" Height="35" HorizontalAlignment="center" VerticalAlignment="center" Content="{Binding SelectedPerson.Age}" DataContext="{Binding ElementName=MyWindow}"/>
<Button Height="35" Click="Button_Click">
Test
</Button>
</StackPanel>
</Grid>
</Window>
I have an ItemTemplateSelector which contains Multiple DataTemplates which have Different DataTypes.
I thus have multiple ItemSources based on Module Selected.
How to bind my ListView with multiple ItemSources based on the module selected?
Explanation:
1)ViewModel_A is my ItemSource and DataTemplateA is my DataTemplate when my Module A is Selected
2)ViewModel_B is my ItemSource DataTemplateB is my DataTemplate when my Module B is Selected
I tried Implementing a BaseViewModel and tried binding the BaseViewModel Type in my ItemSource But this doesn't allow the access of derived class properties.
How to Dynamically Select My ItemSource?
Step 1
First Create a UserControl which contains your ListView in your Xaml and two DependancyProperty for ItemSource and DataTemplate
DataList.Xaml
<UserControl
x:Class="MultipleDataTemplate.DataList"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<Grid>
<ListView ItemsSource="{x:Bind ItemsSource,Mode=OneWay}"></ListView>
</Grid>
</UserControl>
DataList.xaml.cs
public sealed partial class DataList : UserControl
{
public DataList()
{
this.InitializeComponent();
}
#region ItemsSource
public object ItemsSource
{
get { return (object)GetValue(ItemsSourceProperty); }
set { SetValue(ItemsSourceProperty, value); }
}
public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register(nameof(ItemsSource), typeof(object), typeof(DataList), new PropertyMetadata(null));
#endregion
#region ItemTemplate
public DataTemplate ItemTemplate
{
get { return (DataTemplate)GetValue(ItemTemplateProperty); }
set { SetValue(ItemTemplateProperty, value); }
}
public static readonly DependencyProperty ItemTemplateProperty = DependencyProperty.Register(nameof(ItemTemplate), typeof(DataTemplate), typeof(DataList), new PropertyMetadata(null));
#endregion
}
Step 2
Now you can you this usercontrol with any multiple DataTemplate's and multiple itemsource as below
MainPage.xaml
<Page
x:Class="MultipleDataTemplate.Cars"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:MultipleDataTemplate">
<Page.Resources>
<DataTemplate x:Key="CarKey" x:DataType="controls:Car">
<Grid>
<TextBlock Text="{x:Bind carprop1}"></TextBlock>
<TextBlock Text="{x:Bind carprop2}"></TextBlock>
</Grid>
</DataTemplate>
<DataTemplate x:Key="BikeKey" x:DataType="controls:Bike">
<Grid>
<TextBlock Text="{x:Bind Bikeprop1}"></TextBlock>
<TextBlock Text="{x:Bind Bikeprop2}"></TextBlock>
</Grid>
</DataTemplate>
</Page.Resources>
<Grid>
<controls:DataList ItemsSource="{x:Bind ItemSource,Mode=OneWay}" ItemTemplate="{x:Bind ItemTemplate}"></controls:DataList>
<StackPanel>
<Button Content="Cars" Click="CarsClick"/>
<Button Content="Bike" Click="BikeClick"/>
</StackPanel>
</Grid>
</Page>
MainPage.xaml.cs
public sealed partial class Cars : Page, INotifyPropertyChanged
{
public object _ItemSource { get; set; }
public object ItemSource
{
get { return _ItemSource; }
set
{
_ItemSource = value;
this.OnPropertyChanged();
}
}
public DataTemplate _itemTemplate { get; set; }
public DataTemplate ItemTemplate
{
get { return _itemTemplate; }
set
{
_itemTemplate = value;
this.OnPropertyChanged();
}
}
public Cars()
{
this.InitializeComponent();
}
public void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
private void CarsClick(object sender, RoutedEventArgs e)
{
ItemSource = new List<Car>() { new Car() { carprop1 = "1", carprop2 = "2" } };
ItemTemplate = this.Resources["CarKey"] as DataTemplate;
}
private void BikeClick(object sender, RoutedEventArgs e)
{
ItemSource = new List<Bike>() { new Bike() { Bikeprop1 = "1", Bikeprop2 = "2" } };
ItemTemplate = this.Resources["BikeKey"] as DataTemplate;
}
}
public class Car
{
public string carprop1 { get; set; }
public string carprop2 { get; set; }
}
public class Bike
{
public string Bikeprop1 { get; set; }
public string Bikeprop2 { get; set; }
}
i have a class
class Names {
public int id get; set;};
public string name {get ; set};
public string til {set{
if (this.name == "me"){
return "This is me";
}
}
i have a list (ListNames) which contains Names added to it and binding with a combo box
<ComboBox SelectedValue="{Binding Path=id, Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}" ItemsSource="{Binding
ListNames}" DisplayMemberPath="name" SelectedValuePath="id" />
every thing works
i want to display the "Tip" on another label field when user selects an item.
is it possible?
help!
I'm assuming you're using MVVM.
You need to create in your window's viewmodel, a property "CurrentName" of type "Names", binded to the ComboBox SelectedItem property.
This property must raise the NotifyPropertyChanged event.
Then, bind your label field, to this "CurrentName" property.
When the SelectedIem property will change on the combobox, your label field will then be updated.
Something like this:
Your Model:
public class Names
{
public int Id { get; set; }
public string Name { get; set; }
public string Tip {
get
{
return Name == "me" ? "this is me" : "";
}
}
}
Your ViewModel:
public class ViewModel : INotifyPropertyChanged
{
private ObservableCollection<Names> _namesList;
private Names _selectedName;
public ViewModel()
{
NamesList = new ObservableCollection<Names>(new List<Names>
{
new Names() {Id = 1, Name = "John"},
new Names() {Id = 2, Name = "Mary"}
});
}
public ObservableCollection<Names> NamesList
{
get { return _namesList; }
set
{
_namesList = value;
OnPropertyChanged();
}
}
public Names SelectedName
{
get { return _selectedName; }
set
{
_selectedName = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
And finally your View:
<Window x:Class="Combo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Combo="clr-namespace:Combo"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<Combo:ViewModel/>
</Window.DataContext>
<StackPanel>
<ComboBox ItemsSource="{Binding Path=NamesList}" DisplayMemberPath="Name"
SelectedValue="{Binding Path=SelectedName}"/>
<Label Content="{Binding Path=SelectedName.Name}"/>
</StackPanel>