I have the editable ComboBox that using binding to dictionary:
<ComboBox IsEditable="True" ItemsSource="{Binding MyDict}" DisplayMemberPath="Value" SelectedValuePath="Value" SelectedValue="{Binding MyProp}" />
Sometimes I need set in code to property MyProp some different value, that is not presented in the dictionary. In such situation ComboBox is not dispalay the value.
What should I do to ComboBox be able to display arbitrary value in this case?
A ComboBox cannot select arbitrary values. It can only select a value or item that is present in its Items or ItemsSource collection.
So you must add an entry to MyDict before you can select it. You may set the Text property of the ComboBox to a random string, but this won't select any item and set the MyProp property.
Related
I have a ComboBox which takes it's values from ObservableCollection which gets it's data from a XML file.
I am able to display the data from XML to the ComboBox whose code is :
<ComboBox x:Name="ComboBox1" ItemSource="{Binding Path = <Property Name>}" DisplayMemberPath="Name" SelectedItem="{Binding SelectedItem, UpdateSourceTrigger=PropertyChanged}">
Now I want to make modifications such that only some Items in the ComboBox have a checkbox which will be based on the text of the ComboBox Item.
If I use Data Template in ComboBox.ItemTemplate, then all the items of combobox will have the checkbox which I don't want.
Is there any way I can achieve this?
In the ItemTemplate, use the DataTemplate in which there will be triggers that change the Visibility of the flag according to the conditions you need.
I have a table in my database that represents a list of areas. I would like to get all of these items in this list and bind them to a combobox dropdown in my datagrid. This currently works, and my grid column displays this dropdown. However, when I select an item in the cell and move to the next row, the cell becomes blank. Also, if the entry in the database has a saved value of "area1", and my dropdown list has "area1,area2,area3,etc", when the grid loads, it doesn't autoselect area1, the cell is simply blank.
In my model:
comboboxColumn1.ItemsSource = ctx.AREAS;//db context loading all areas into combobox
In my xaml:
<DataGrid.Columns>
<DataGridComboBoxColumn DisplayMemberPath="Name" Header="some header" x:Name="comboboxColumn1" SelectedValueBinding="{Binding Name}" />
....
How would I go about setting this selected value so that it is equal to whatever entry is in the db?
You need to set the SelectedValuePath value to your variable property. The DisplayMemberPath is for what is shown, and SelectedValuePath is what is selected. SelectedItem is the actual item that is selected.
I have a view with a ComboBox like this
<ComboBox Name="cmbPurpose" DisplayMemberPath="#value" SelectedValuePath="#key"
ItemsSource="{Binding Source={StaticResource Purposes}, XPath=purpose}"
SelectedItem="{Binding Path=Purpose, Mode=TwoWay}" />
I also set the DataContext of the view to my viewmodel. On my viewmodel i have a property 'Purpose' of type 'XmlElement' bound to SelectedItem. I would have liked it to be a string that corresponded to the #key in my xml, but i can live with this since it makes sence in a view-viewmodel context.
When i change the ComboBox, i can observe that the value in my viewmodel changes accordingly - which is as expected (and good).
When i populate my view with the viewmodel, i need some defaults set (also it will be used to edit a model later so i will need to be able to set all properties on my viewmodel). How do i set the correct value on my viewmodel's 'Purpose' property? The data from my model is really equal to the #key of my xml, but the viewmodel or whatever populates my viewmodel have no way of knowing what resource to look in since it needs to set an XmlElement.
So what is best practise here? Should i move the static resource to my viewmodel or is there another way of solving this? How is this normally done? Is static resources just bad in this situation? It would be perfect if i could just make the viewmodel.Purpose into a string and have it bind to the #key instead of the whole object - that should solve the problem as i could both set and read viewmodel.Purpose without having to think of the source being xml, right?
EDIT: If there was a way to do SelectedKey="{Binding Path=Purpose, Mode=TwoWay}" and changing the viewmodel.Purpose to a string, then the problem would be sovled.
You can set the selected value to the key.... simply use SelectedValue instead of SelectedItem, and bind it to a string value which corresponds with the an #key in your ItemsSource
<ComboBox Name="cmbPurpose" DisplayMemberPath="#value" SelectedValuePath="#key"
ItemsSource="{Binding Source={StaticResource Purposes}, XPath=purpose}"
SelectedValue="{Binding Path=PurposeKey, Mode=TwoWay}" />
It should be noted that ComboBoxes compare items by reference, so if you do use SelectedItem then the item that is bound needs to contain the exact same reference in memory as the item in the ItemsSource.
For example,
SelectedItem = new SomeItem(Key = 1); // Won't work
SelectedItem = SomeStaticList.FirstOrDefault(p => p.Key == 1); // Will work
I am having a ComboBox in wpf which is having its source as a IDictionary<Key, String> where 'Key' is the custom key. The ComboBox is defined as follows:
<ComboBox
x:Name="MD_PDIR_COMBO_SOURCE"
Grid.Row="0"
Style="{DynamicResource USButtonComboBoxStyle}"
Margin="14,5"
VerticalAlignment="Top"
HorizontalAlignment="Stretch"
ItemsSource="{Binding Path=SourcesComboList}"
DisplayMemberPath="Value"
SelectedValuePath="Key"
SelectedValue="{Binding Path=SelectedSource}"
SelectionChanged="MD_PDIR_COMBO_SOURCE_SelectionChanged"
/>
Now the issue I am facing is, although DisplayMemberPath is set to the "Value" of the dictionary which is a String, the Visual text being displayed in the combo box on selecting an item is BLANK/EMPTY.
Although all the desired functions on combo box selection change are happening correctly but the values/text is not shown after we select an item.
Kindly help!
Does your style set the ItemTemplate at all?
Setting DisplayMemberPath is a shortcut way of saying the ItemTemplate should be a TextBlock with it's Text bound to whatever is in DisplayMemberPath, so setting the ItemTemplate in addition to DispalyMemberPath will override it and make DisplayMemberPath useless
This work OK
public string Value{ get; set; }
This doesen't work !
public string Value;
Conclusion: DisplayMemberPath indicates a property of your item object not a field. Use getter and setter: { get; set; }
i assume that you have a dictionary like this?
SourcesComboList = Dictionary<string,string>();
if you just wanna check wether your Displaymemberpath works alter your combobox to this
<ComboBox Grid.Row="0"
ItemsSource="{Binding Path=SourcesComboList}"
DisplayMemberPath="Value"
SelectedValuePath="Key">
</ComboBox>
if this is working the problem is not DisplayMemberPath :)
I had the similar problem with internal property.
The DisplayMemberPath is working only for public properties.
I guess the issue with the original question might be ComboBox does not query the Dictionary to know its Item Type instead it looks at the individual Dictionary Item (not the Value) which does not have any Key and Value properties.
How can I maintain selection on a combobox if the currently selected item is replaced in the ItemsSource collection? In this case the collection is an ObservableCollection and of course if the currently selected item is replaced the combobox loses its selection - nothing is selected.
The ComboBox looks like:
<ComboBox
Name="combobox"
SelectedValuePath="Id"
DisplayMemberPath="Description"
SelectedValue="{Binding Source={StaticResource cvs}, Path=Id, Mode=TwoWay}"/>
I cannot simply set the selected item on the combobox manually each time as the collection is manipulated in another generic class I cannot touch!
Thanks!
you bind the selectedVaule to your Id Property. so if you want the new added Item to be the selected one, just set your Id property to the new Item and call OnPropertyChanged("Id")
myCollection.Remove(oldItem);
myCollection.Add(newItem);
Id = newItem;
OnPropertyChanged("Id")
Use this code to select the new item:
combobox.SelectedItem = newItem;
UPDATE:
If the combobox is unknown to the part of the code that replaces the item, you need to do something like the following:
Subscribe to the CollectionChanged event of your collection.
When the event is fired and it says that a new item was added, execute the code as shown above.