WPF - Editable combobox text overwritten by source on load - c#

I have an editable combobox that also has an item source which is effectively used to prompt users with some standard entries for that box whilst giving them the freedom to enter custom entries if they wish. So, everything works fine accept when I bind to a property with a value (which is not one off the list) it sets the comboboxes text to the first item in the item source. Just to be clear, the following steps demonstrate the issue.
I open the View with a clean Model (all the properties are null/default values
I enter a custom value into the editable combobox
I save the Model
I close the View
I re-open the View with the previously saved Model
The custom value which I saved should be displayed in the editable combobox, however it is overwritten by the first value in the item source list
Note: The value in the Model property is not changed, this issue is purely visual.
So, how can I stop the itemsource overwriting custom entries?
Here is the combo box XAML:
<ComboBox IsEditable="True" ItemsSource="{Binding Contact_Types, Mode=OneTime, Source={StaticResource Resources}}" Text="{Binding Model.type, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" />

Related

How to attach a property in WPF/XAML with NULL as initial value

I have a datagrid and I want to show some details of the currently selected row in some textboxes above the datagrid. I am working with Telerik's grid and have SelectionUnit=Mixed and SelectionMode=Extended. Thus SelectedItem and SelectedItems are always null.
My working solution is that I created an attached property which provides the values of that row if only cells from one row are selected and dummy values if cells from multiple values are selected.
that part of the grid is defined as:
<telerik:RadGridView b:myBehavior.CurrentRow="{Binding Path=Data.SelectedRow, Source={StaticResource DataContextProxy}}" Name="myGridView" ...>
and the values are referenced in the textbox with this code:
<TextBox Text="{Binding Path=(b:myBehavior.CurrentRow).TextValue, ElementName=myGridView}" />
As you can see I had to create a binding do a property in my viewModel. Is there a way to initalize the attached property without using the viewmodel? Either by providing a dummy record or NULL?
If I set b:myBehavior.CurrentRow="" I get an exception (invalid value). what do i need to do here to get it running?
Thanks to #Clemens for pointing me into the right direction. My solution to avoid an unnecessary roundtrip to the viewmodel was to create an object in the Usercontrols resources
<repositories:FahrzeugFlatRecord x:Key="myObj" />
and then bind it like so:
<telerik:RadGridView b:myBehavior.CurrentRow="{Binding Source={StaticResource myObj}}"...>
the TextBox remains unchanged. This solution was necessary as I have a PropertyChangedCallback in my behavior that registers an EventListener. If this was not the case, it would be sufficient to call to bind that behavior:
<telerik:RadGridView b:myBehavior.CurrentRow="{x:Null}"...>

Retrieving previously saved combobox items from wpf datagrid

I am new to WPF. below is the XAML code.
<dg:DataGrid.Columns>
<dg:DataGridTemplateColumn Header="Cars" MinWidth="70" Width="70">
<dg:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox Name="cboCars" MinWidth="70" ItemsSource="{Binding Path=Cars}" Width="70">
<ComboBoxItem>BMW</ComboBoxItem>
<ComboBoxItem>Benz</ComboBoxItem>
<ComboBoxItem>Audi</ComboBoxItem>
</ComboBox>
</DataTemplate>
</dg:DataGridTemplateColumn.CellTemplate>
</dg:DataGridTemplateColumn>
So each row contains a combo box and it contains all the 3 car names are there as the combo box item and user can choose a car from the drop down and save it. But when taking back the value from the Database, I can't display the exact car in the grid row as the previously saved item.Suppose now if i choose "Audi" and save the form and later on when i tried to retrive the saved data, the combobox will be displaying nothing!!! How to show the exact car in the grid ? Please help me.
Have a look at selection. You can define a property in your view model and bind it to the SelectedItem / SelectedValue of your combobox. After loading data you can set this property and this item is selected in your combobox.
See here: https://stackoverflow.com/a/23168586/8002376

Combobox SelectedItem is not retrieved properly

I have saved all combobox values which are added dynmaically to a collection.
No i want to retrieve the info. When I retrieve it my combobox values are not displayed in it.
We use Telerik component here
<tele:RadComboBox HorizontalAlignment="Stretch" DisplayMemberPath="content" ItemsSource="{Binding ManyValue,Mode=TwoWay}" SelectedItem="{Binding MyValue, Mode=OneWayToSource, UpdateSourceTrigger=PropertyChanged}">
ManyValue is a dropdown of values which has id,content
Myvalue is selected value what I have selected in combobox
ManyValue is a collection of viewmodel to combobox.
MyValue is a property of ViewModel i.e. selected item of comboobox.
This is happening correctly when I select, But when I retrieve the data,In collection Items are present but something wrong in Binding so that am not able to display it.
I do the save properly. But when I retrieve unable to load the already selected item in combobox.
Can anyone help?
Set the SelectedItem,SelectedValue and SelectedValuePath did the trick for me

How to bind different properties to SelectedItem and SelectedIValue of ComboBox?

I have a thread that updates the current Mode property every second. I also want an option to be able to set a mode within the same cell in datagrid. So, in not editing mode I just show the mode. In editing mode, I show a populated ComboBox.
Now,
to be able to show the selected item in ComboBox, when I enter the editing mode, I bind the SelectedItem to Mode.
to be able to get the changes back to the ViewModel I bind SelectedValue to a different property. ( I need to bind to a different property since 'Mode' is updated every second and will overwrite the selected value).
The problem is that though SelectedItem is bound with Mode=OneTime it still triggers SelectedValue property. I want the SelectedValue to be triggered only when user select a value.
I hope it's clear what I'm trying to do. So, how I can achieve this? Other approaches are welcome (even if I need to use a different control).
<DataGridTemplateColumn Header="Mode">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Mode}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding Source={StaticResource Modes}}"
SelectedItem="{Binding Mode, Mode=OneTime}"
SelectedValue="{Binding ModeToSet, Mode=OneWayToSource}"
/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
The premise of what needs to be done is not attainable due to the way the combobox works and how Mode is constantly changing in the background.
Why?
The problem is that though SelectedItem is bound with Mode=OneTime it
still triggers SelectedValue property.
As it should. OneTime as per the docs (BindingMode Enumeration) states:
"Updates the binding target when the application starts or when the data context changes."
The data context as per your design is always changing once a second. If one reads farther into the description it states
"This type of binding is appropriate if you are using data where either a snapshot of the current state is appropriate to use or the data is truly static. ... This is essentially a simpler form of OneWay binding..."
And if one reads up on OneWay bindings
"Updates the binding target (target) property when the binding source (source) changes. This type of binding is appropriate if the control being bound is implicitly read-only."
A combo box is ultimately designed to change both SelectedItem and to get the value off of SelectedItem into SelectedValue
I want the SelectedValue to be triggered only when user select a value.
The problem is not going out of the control, it is what is coming in....
Create a test project and the combobox behaves the way you specify, selected value is only triggered when a user selects a value. Comboboxes only sets the SelectedX properties when a choice is made or an outside value has changed one so it changes the other.
Since Mode is constantly changing it is pushing the change into the selection, not visa versa.
Suggestion To Fix
I suggest you take a snapshot of mode and place that into a ModeOnEdit variable and bind that. When the user makes the selection, capture the event and change the actual Mode.
Test Project
Bind to your own data source, mine was Ships. Ships is a list with and Name as a property on that object. ToString on the ship object returns Name.
Here is the result, there are two textboxes which show the state of the selected item/value. A button to set the selected value and the combobox itself.
<Label Grid.Row="1" Grid.Column="1">SelectedItem</Label>
<TextBlock Grid.Row="1" Grid.Column="2" Text="{Binding SelectedItem, ElementName=cbMain}"/>
<Label Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="2">SelectedValue</Label>
<TextBlock Grid.Row="3" Grid.Column="2" Text="{Binding SelectedValue, ElementName=cbMain}"/>
<Button Grid.Row="5" Grid.Column="1" Click="ChangeSelectedValue">Set Selected Value</Button>
<ComboBox Name="cbMain"
Grid.Row="5"
Grid.Column="2"
ItemsSource="{Binding Ships}"
SelectedValuePath="Name"/>
-- Code behind
private void ChangeSelectedValue(object sender, RoutedEventArgs e)
{
cbMain.SelectedValue = "Pacific Silver";
}

Silverlight ItemsControl and ComboBox

Im cleaning up this question and going to put in an example that makes sense to me..hopefully for you too...
so lets say i have an Items control. This control is bound to an observable collection of NBA Basketball teams (Lakers, Heat, Knicks...ect). In this observable collection of NBATeams I have a property of FavoritePlayer. I have a datatemplate that lays out how this is going to look inside the Items Control. I have a textbox which displays the team name. (this could be/should be read only..its not now) but it displays the team name.. LA Lakers. the second item in my items control is a combobox. this combo box will ultimately display my favorite player on each team.
The itemssource on the combobox is from a lookup value i have. It displays all the people on the team and the displaymemberpath on this combobox is "DisplayText"...I need my selected item on this combobox to be shown. so if my favorite player is Kobe Bryant the combo box should display this.
<telerik:RadComboBox Grid.Row="0" Grid.Column="9" Width="150" EmptyText="--Select Player--"
ItemsSource="{Binding PlayerList}"
SelectedItem="{Binding FavoritePlayer, Mode=TwoWay}"
DisplayMemberPath="DisplayText" HorizontalAlignment="Left"></telerik:RadComboBox>
I am used to just having textblocks in a listbox and then when an item is selected from within that listbox i use that selected item to bind my comboboxes that live outside of my listbox. Now i actually have the combobox in the listbox(ItemsControl now). So Im wondering the best way to bind the combobox from within an ItemsControl
I initially was just having issues getting the players to show up in the combobox..but I solved that by doing the code below.
I found my first issue of just binding the items source to the combo box from within an items control.
I had to set the bindings to look like this.
ItemsSource="{Binding DataContext.PlayerList, ElementName=ItemsControlNBATeams}"
so i had to set the name of the items control and use that in the element name and set the path = to DataContext.PlayerList. this now brings up the items in my combo box..what it doesnt do is set the selecteditem of my combo box.
Not very clear about your you are asking but does this answer your question
<ListBox ItemsSource="{Binding}" x:Name="ListBox1"></ListBox>
<TextBox Text="{Binding SelectedItem, ElementName=ListBox1}"> </TextBox>

Categories

Resources