How do I bind the SelectedValue of a ComboBox to a Property? - wpf

I've got a ComboBox with an ItemsSource which I've bound to a List(Of String).
What I'd like to do is have the XAML update a String property when the SelectedValue of the ComboBox changes. I've seen a whole bunch of examples for TextBoxes which use
Text="{Binding Path=MyString}"
sort of stuff, but I don't really think that'll be the way to go if, in future, I need to change the ItemsSource to a List(Of ObscureObject)...

Binding to the selected property of a combobox is fairly simple.
XAML :
<ComboBox ItemsSource={Binding Path=MyCollection} SelectedItem={Binding Path=MyItem}/>
CodeBehind :
public List<string> MyCollection {get; set;}
public string MyItem {get; set;}
If you want to insert text into the selected item, you'll need to use INotifyPropertyChanged
as for your scalability issue, its a fairly minor change to update the type of a property to reflect a collection. Otherwise you could try binding to an Object although that would mean you would constantly have to recast the object back to the state you want.

You can use SelectedItem property of ComboBox to achieve this.
<ComboBox ItemsSource="{Binding Path=YouList}"
SelectedItem="{Binding Path=MyString}" />
When you change your list in future you will have to bind the SelectedItem with a property of your objects type.
Have a look at this article for more details -
http://japikse.blogspot.com/2008/10/wpf-combobox-selecteditem-selectedvalue.html

Related

WPF DataTemplate with Binding

A WPF ComboBox/ListBox itemtemplate/datatemplate question please.
Let's say that I set DisplayMember="Name", this is equivalent to
<DataTemplate>
<TextBox Text="{Binding Name}" />
</DataTemplate>
"Name" is a field in my view model.
Now, if DisplayMember="{Binding Name}", "Name" is no longer a property in my view model but instead contains the name of the property in my view model that I want to display. Using an ItemTemplate, how would I set this up? Thank you in advance.
DisplayMemberPath is a property of the ItemsControl. And its binding path will be resolved relative to the ItemsControl's DataContext, not its items.
Example (pseudo code without INPC interface implementation):
public class ViewModel
{
// This sets the string name of the property (or the path to it)
// to be displayed in the items.
public string DisplayNameProperty {get; set;} = "Name" // Or = "Surname"
// Items Source
public IEnumerable Items {get; set;}
}
<ItemsControl ItemsSource="{Binding Items}"
DisplayMemberPath="{Binding DisplayNameProperty}"/>
The binding in the DisplayMemberPath property will allow you to control from the ViewModel which property will be displayed in ItemsControl's items.
But in practice, such a task is extremely rare.
Personally, in my practice, such a need has never arisen.

ListBox with ItemsSource of List<Dictionary<string, object>>

I'm setting the ItemsSource of a ListBox to the values of a ValueSet instance. Here is ValueSet:
public class ValueSet
{
public string valuetype;
public List<Dictionary<string, object>> values;
public double count;
}
Of course, the ListBox displays each item as "(Collection)" (list box on the right):
Each Dictionary<string,object> element in values is expected to have a pair with a key of text. I'd like for the ListBox to display the value of this pair. Can this be done by setting the DisplayMemberPath of the ListBox? If so what should it be set to? If not, what's a good way to achieve this?
At the very least you should be able to bind using the indexer syntax for binding "[text]". Use the ItemTemplate of the ListBox:
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=[text]}" />
You could also instead try setting DisplayMemberPath="[text]", but I have no idea whether that would work.
Using DisplayMemberPath we can able to achieve this by setting the Binding as Value. Please follow the below code snippet.
DisplayMemberPath="Value"

Bind Combobox Itemsource to Static Dictionary (Silverlight)

I am trying to bind the ItemsSource of my ComboBox to a static dictionary I have on a static class.
In WPF I would use the following which would work fine:
ItemSource="{x:Static objectModel:LocaleHelper.FriendlyNames}"
Where LocaleHelper is the class name and FriendlyNames is the dictionary property of which I wish to bind to.
However in Silverlight I get an error to do with the type x:Static not being found.
Could anyone explain to me what the issue is and the workaround?
I have looked around but couldn't find any detailed explanations.
Sorry if this is a simple issue - I'm new to Silverlight and also WPF in general.
EDIT:
After having done some more reading it looks like silverlight does not support static resources. Furthermore Dictionaries do not seem to update property changed / support DisplayMemberPath & SelectedValue so having the dictionary as a field in my viewmodel doesn't seem to be an option either.
You can only bind to non-static public properties (not fields). But you can use any "carrier" for those properties (so you are not forced to have those properties in the ViewModel). Let's see...
<Resources>
<LocaleHelperWrapper x:Key="Wrapper"/>
</Resources>
<ComboBox ItemsSource="{Binding Path=FriendlyNames,
Source={StaticResource Wrapper}}"/>
And the wrapper code:
public class LocaleHelperWrapper
{
public Dictionary<string, string> FriendlyNames
{
get { return LocaleHelper.FriendlyNames; }
}
}
[Edit] The ComboBox supports DisplayMemberPath and SelectedValue. Assuming you want to use the ComboBox to select the Key and display the Value of you Dictionary's KeyValuePairs:
<ComboBox
DisplayMemberPath="Value"
SelectedValuePath="Key"
SelectedValue="{Binding Path=MySelectionViewModel.SelectedKey, Mode=TwoWay}"
ItemsSource="..."/>
If it's merely an issue of binding to a collection, you might as well do it in the constructor of the ViewModel. Further consider using an ObservableCollection in case your static collection changes over time.

WPF User Control Binding get data

I'm new to WPF and binding stuff. I was trying to find a solution to my problem, but still missing something ;/
I would like to get data from TextBox which is in UserControl and put it to a property in which is in a main window, on way it work, but other not ;/
I have a simple class
public class User
{
public string Name {get; set;}
public string Age {get; set;}
}
and a simple user control called UserDetails with a two TextBoxs
<TextBox Text="{Bind Name}" />
<TextBox Text="{Bind Age}" />
UserDetails UC is placed on main window like this:
<uc:UserDetails DataContext="{Binding User, Mode=TwoWay}" />
and in MainWindow ViewModel I have a property
public User User { get; set;}
on MainWindow there is also a button that on click should fill up User property with data from UserDetials UC.
It's quite late now and I need to have it done by morning, so any straight solution would be appreciated.
Any ideas how to do it ? The example above is very simple, but If you could show me the way how to do it, I could handle rest of my problem.
Here are some things to try:
Make sure you're setting your view model to the MainWindow's DataContext. Even if you're not using a separate class for your view model and are just using code-behind, you need to assign the DataContext.
It might just be a typo, but in your text boxes, you've written {Bind Name} when it should be {Binding Path=Name, Mode=TwoWay} and the same for the Age. You need to set the binding mode to two way on the property, not on the class as you have in your example.
You need to implement the INotifyPropertyChanged interface and fire the PropertyChanged event in the property setter. You'll need to do it for your MainViewModel and User classes. Here's an example of how it is done.

WPF listview display converter

I have a collection of objects that derive from a Person class and I want to bind this collection to the ItemsSource of a ListView.
I want to specify a string to display in the ListView Items. This string will be a composite of properties found on the derived classes.
I also want to bind the SelectedItem of the ListView to a property of type Person in my view model.
As far as I see it I need a string converter for my display string but I'm unsure how to bind to the items within the ItemsSource to generate the composite display string.
Can anyone give me a pointer?
Thanks.
You can either overwrite the ToString() method of your derived classes to return your composite display string, or you can create a Converter like you are suggesting and pass it the entire Item. The converter would then check that the item is of a specified type, and if so compose a string of whatever properties you want.
you dont need the StringConverter, you need DataTemplate
using DataTemplate, you can choose how you would like to display you data as an item in your listBox.
If you could consider your derived class a ViewModel then you could just add a property to that class and then display it in the ListView ItemTemplate. Or like Rachel suggested override your ToString Method and then in your display binding simply write "{Binding}" which will force WPF to call the ToString method
e.g.
public class DerivedPerson : Person
{
public string DisplayString
{
get
{
return string.Format("{0} {1}",FirstName,LastName);
}
}
}
And you xaml:
<ListView ItemsSource="{Binding PersonList}" SelectedItem="{Binding SelectedPerson}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text={Binding DisplayString}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

Resources