I have a ComboBox that is that is being populated from an ItemsSource collection. I am populating all the customers into an Observable Collection, and binding it to the collection, like so.
<ComboBox ItemsSource="{Binding Path=Customers}"
SelectedValue="{Binding CustomerKey}"
DisplayMemberPath="FullName" SelectedValuePath="{Binding Key}" />
In this same view, I have a data grid with basic information with orders in it. When an order is selected, within the view model I am getting a more detailed record for the order. What I want to do is update the view with customer information for the newly selected order.
I was trying to set the CustomerKey, and then selected that Customer based on it's key -- I think I am doing this all wrong though. How can I accomplish this?
The SelectedValuePath property of the ComboBox should be set to a string (and not to a binding) that specifies the name of the property of the Customer class where the key is stored:
<ComboBox ItemsSource="{Binding Path=Customers}"
SelectedValue="{Binding CustomerKey}"
DisplayMemberPath="FullName" SelectedValuePath="Key" />
This will work provided that the Customer class has a FullName and a Key property and that the Key property has the same type as the CustomerKey property of the view model.
A customer with a key matching the value that you set the CustomerKey property to must also be present in the Customers collection that you bind the ComboBox to for an item to be selected.
Related
Note: I'm using Mahapps.Metro if some parameters seem odd.
So, I have a Model called User, which has a StateId.
Combobox is filled with States, so when a state is selected I put the Id of the selected state into User.StateId like this:
<ComboBox
Grid.Column="0"
Margin="0,5,0,0"
mah:TextBoxHelper.ClearTextButton="True"
mah:TextBoxHelper.Watermark="Select a State..."
ItemsSource="{Binding States, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
SelectedItem="{Binding SelectedState, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
SelectedValue="{Binding User.StateId, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
SelectedValuePath="Id" />
And this works just fine. However, what if I wanted to put another parameter of the selected item into the User model? Let's say User also has a property called StateName, and when I select a new State, I pass both the State.Id and State.Name into the User.StateId and User.StateName?
Hopefully this wasn't too confusing. Thanks!
SelectedValue and SelectedItem can only be bound to a single source property. But you should be able to bind SelectedItem to a State property of the User class rather than trying to set both StateId and StateName.
If the User class doesn't have a State property, you could bind to a SelectedState property of a view model (which it seems like you already are) that then in turn sets the StateId and StateName properties of the user. You should only bind to either SelectedItem or SelectedValue anyway.
I have an Entity table which lists ISO Country Codes and their descriptions in order to populate a ComboBox. I then have another table which sets a 'Nationality' to the selected value of the ComboBox. I have no foreign-key constraints between the IsoCountryCodes and my other table.
I want to be able to set the SelectedItem of the ComboBox to the selected IsoCountryCode, but I want to save the SelectedValue to the 'Nationality' field.
I've tried setting the SelectedItem of the ComboBox to my 'Nationality' (string) field but it is just doing a ToString() on the IsoCountryCode. When I set the 'Text' field instead of SelectedItem, it is saving the DisplayPath value to the 'Nationality' field.
I was wondering if there was a way to get the ValuePath value to save to the field without any foreign key constraints, whilst still displaying a valid DisplayPath to the user?
Example of IsoCountryCode table:
IsoCode IsoDescription
'GBR' 'United Kingdom'
'USA' 'United States of America'
Example of the other table:
PassengerId PassengerName PassengerNationality PassengerDocumentIssuingCountry
1 'Carter, John' 'GBR' 'USA'
And my current Xaml:
<xctk:WatermarkComboBox x:Name="uxNationalityCmbo" Margin="0,0,5,5" Watermark="Nationality"
Grid.Row="2" ItemsSource="{Binding CountryCodeCollection}" SelectedValuePath="IsoCode" DisplayMemberPath="IsoDescription"
IsTextSearchEnabled="True" Text="{Binding SelectedPassenger.PassengerNationality, TargetNullValue=''}"/>
Changing the selected value now would to USA would change the entity PassengerNationality to 'United States of America', whereas I need 'USA'
You should bind the SelectedValue property to the PassengerNationality source property:
<xctk:WatermarkComboBox x:Name="uxNationalityCmbo" Margin="0,0,5,5" Watermark="Nationality"
Grid.Row="2" ItemsSource="{Binding CountryCodeCollection}" SelectedValuePath="IsoCode" DisplayMemberPath="IsoDescription"
IsTextSearchEnabled="True" SelectedValue="{Binding SelectedPassenger.PassengerNationality, TargetNullValue=''}"/>
I have a combobox with items like below:
{[1, US]}
{[2, UK]}
My combobox will display it with the Value. My problem is I can't set the SelectedValue property of my combobox.
<ComboBox Name="cbSource" Grid.Row="1" Grid.Column="3"
ItemsSource="{Binding Datas.Countries, Mode=OneWay}"
SelectedValue="{Binding CurrentObject.Country, Mode=TwoWay}"
DisplayMemberPath="Value" SelectedValuePath="Key"></ComboBox>
Now my CurrentObject.Country is a string property with a value of UK. I also tried this one below but no luck.
DisplayMemberPath="Value" SelectedValuePath="Value"
What can I do here?
It is not possible to achieve your behavior using a key value pair. See the example below.
Just create a class having 2 properties one for key and one for value. Then bind a collection of this class as the itemssource and bind the selectedvalue to a string property. Ie Datas.Countries is the collection of the class.
<ComboBox Name="cbSource" Grid.Row="1" Grid.Column="3"
ItemsSource="{Binding Datas.Countries, Mode=OneWay}"
SelectedValue="{Binding SomePropertyToHoldKeyValue, Mode=TwoWay}"
DisplayMemberPath="Value" SelectedValuePath="Key"></ComboBox>
I think we can understand the difference between SelectedItem, SelectedValue, DisplayMemberPath and SelectedValuePath better with an example. See this class:
public class Employee
{
public int Id;
public string Name;
}
and the following xaml:
<ComboBox ItemsSource="{Binding Source={StaticResource Employees}}"
DisplayMemberPath="Name"
SelectedValuePath="Id"/>
DisplayMemberPath points to the Name property, so the value displayed in the ComboBox and the Employee entries contained in the drop down list, will be the Name property of the Employee object.
To understand the other two, you should first understand SelectedItem. SelectedItem will return the currently selected Employee object from the ComboBox. You can also assign SelectedItem with an Employee object to set the current selection in the ComboBox.
SelectedValuePath points to Id, which means you can get the Id of currently selected Employee by using SelectedValue. You can also set the currently selected Employee in the ComboBox by setting the SelectedValue to an Id (which we assume will be present in the Employees list).
I have a combo box and button as such
<ComboBox ItemsSource="{Binding MessageTypesList}"
DisplayMemberPath="MessageType"
SelectedValue="MessageType" />
<Button Content="Search"
Command="{Binding Path=SearchMessageTypes}"
x:Name="SearchMessageTypeButton"/>
The MessageTypesList list is generated from a SQL query and once the Message Type is selected from the list the Search button needs to pass the selected value to a string property in my ViewMainModel.
When I debug the application the value passed to the MessageType property is always NULL. I have this working for a similar date time searchs but cant see how to pass the MessageType value in my XAML to the MessageType propery form binding generated lists.
You should bind the SelectedValue property to a property in your viewmodel.
Create a property in your viewmodel:
public MessageType SelectedType {get;set;}
Bind selectedItem to this property in XAML:
<ComboBox ItemsSource="{Binding MessageTypesList}" SelectedItem="{Binding SelectedType, Mode=TwoWay" />
I have a datagrid of rows which contain data read from a web server and values I want to write into a webserver. I write the values in getting the user to input a number into the appropriate column and click an adjacent text box;
<DataGrid x:Name="datagridDERControl" HorizontalAlignment="Center" VerticalAlignment="Center" Background="#FF322D2D" Height="382" Margin="10,78,10,10" Width="972" ItemsSource="{Binding Path=NFDataSource, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<DataGrid.Columns>
<DataGridTemplateColumn Width="100" Header="Write Set Point">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Width="100" Text="{Binding Path=WriteSetPoint, Mode=OneWayToSource, UpdateSourceTrigger=PropertyChanged}"></TextBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Width="100" Header="Global Trip">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Name="buttonGlobalTrip" Width="100" Click="buttonGlobalTrip_Click"></Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid
How do I extract the specific textbox string per row to use in my view model.
It's always difficult to answer a question where the relevant details have been omitted by the question author. However, I shall try!
You have data bound (presumably) a collection property named NFDataSource to your DataGrid.ItemsSource property. That is the collection that represents the data in your DataGrid, so to 'extract' a specific value, you need to look into your data items in your collection.
One handy property in the DataGrid class is the SelectedItem property. this enables you to data bind an object (of the same type as those in your NFDataSource collection) to this property, which accesses the data object behind the row that is currently selected in the UI:
<DataGrid ItemsSource="{Binding NFDataSource}" SelectedItem="{Binding SelectedItem}" />
Now you can utilise your SelectedItem property to access the values from the selected row in the DataGrid:
string someValue = SelectedItem.SomeProperty;
As you tagged this with MVVM and databinding, I'll assume you're using these and have just got muddled.
"I have a datagrid of rows which contain data read from a web server
and values I want to write into a webserver."
So your viewmodel has a property, which is a collection of a custom class, that represents data fetched from a webservers.
"I write the values in getting the user to input a number into the
appropriate column and click an adjacent text box"
So this VM property is two-way bound to a datagrid, so that each item in the collection represents 'one row', and the properties on those items represent your 'columns'. The user can make changes to the UI displayed values, and because of the two way databinding the VM property is also updated.
"How do I extract the specific textbox string per row to use in my
view model."
Why do you need the specific textbox string, if it is databound to a property (or rather to a property on a class contained in a collection) in your VM anyway? If you've set up your VM this way, and are using databinding, you rarely need to worry about UI specific things such as which row in a datagrid is clicked.
As Sheridan points out though, you can also bind to properties on the datagrid such as SelectedItem so that you can perform additional operations beyond just reading/writing data. SelectedItem for your datagrid will be of the type that populates your VM collection, so will have the appropriate properties.
For example, if your VM collection is an IQueryable<Person> and that is bound to the ItemsSource of the datagrid then the SelectedItem will be of type Person. You could then have a VM property called SelectedPerson which is bound to that SelectedItem, and access things like SelectedPerson.Name etc.