How to update combo box item in wpf? - c#

I have combo box in wpf application. On combo box selectionChanged event i have added one more item in combo box. I have bind the combo box with wvvm architecture. On selectionchanged my list updated but combo box item not refresh.
My xaml code as follow:
<ComboBox Name="cmb" SelectionChanged="cmb_SelectionChanged"
ItemsSource="{Binding Source={StaticResource cmbList}}"
SelectedValue="{Binding Listvalue}" DisplayMemberPath="ItemName" SelectedValuePath="itemName" >
</ComboBox>
I have use following code for sectionChanged:
private void cmb_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
DropDownItem newItemsValue = new DropDownItem { ID = 1, itemName = "newValue", strID = "newValue" };
this.objcmbList.cmbList.Add(newItemsValue);
(FindResource("CmbList") as ObjectDataProvider).ObjectInstance = this;
(FindResource("CmbList") as ObjectDataProvider).Refresh();
}
Here my list has been updated but combo box not updated.
May be Error is combo box in use.
so how can i refresh my combo box item on selection changed event.

Binding to a standard List won't automatically update in WPF. Instead of using a List use an ObservableCollection in your view model instead eg:
Public ObservableCollection<string> cmbList = New ObservableCollection<string>()
and then bind to it in your XAML:
<ComboBox Name="cmb" SelectionChanged="cmb_SelectionChanged"
ItemsSource="{Binding Path=cmbList}}"
SelectedValue="{Binding Listvalue}" DisplayMemberPath="ItemName" SelectedValuePath="itemName" >
</ComboBox>

Related

How to filter and auto suggest Combo Box items based on text entered?

I have followed the following links to create a custom combo box. I have added a list of combo box items using c#.
If I type text in the custom combo box it is not filtering the items based on the search text whether an item contains the word.
The custom combo box just listing all the items in it.
I want my combo box to act like if type word it should filter the result and auto-suggest in the combo box search.
<local:FilteredComboBox x:Name="FilteredCmb" IsEditable="True"
IsTextSearchEnabled="True"
Padding="4 3"
MinWidth="200" Grid.ColumnSpan="6"
Grid.Column="2" Margin="0,77,0,49" Grid.Row="1" />
How to achieve this?
Is this possible with a Default combo box.
The default combo box auto-suggests the items which start with the entered text not with checking whether the word is contained in an item.
Create Custom ComboBox1
Custom ComboBox2
I have used combo box key up event to filter the result.
<local:FilteredComboBox x:Name="FilteredCmb" IsEditable="True"
IsTextSearchEnabled="False" **KeyUp="FilteredCmb_KeyUp"** Padding="4 3" MinWidth="200"
Grid.ColumnSpan="6" Grid.Column="2" Margin="0,77,0,49" Grid.Row="1" />
C# Code
private void FilteredCmb_KeyUp(object sender, KeyEventArgs e)
{
List<BoxItem> filteredItems = new List<BoxItem>();
for (int i = 0; i < cmbItems.Count; i++)
{
string currentItem = cmbItems[i].Text.ToLower();
// get the text in the editable combo box
string typedText = FilteredCmb.Text.ToLower();
if (currentItem.Contains(typedText))
{
filteredItems.Add(cmbItems[i]);
}
}
// Clear the combo box before adding new items to Combo Box
foreach(BoxItem item in filteredItems)
{
FilteredCmb.Items.Add(item);
}
FilteredCmb.IsDropDownOpen = true;
}

SelectionChanged Combobox WPF

I want to populate a ComboBox based on selection of other ComboBox.
Both combo boxes are populate from database using WCF.
My problem is that on first selection it's not working (just after second selection it's work and it's show results from first selection).
XAML
<ComboBox
x:Name="selClientCombo"
SelectionChanged="listEchipamente"
IsEditable="True"
SelectedIndex="-1"
HorizontalAlignment="Left"
Margin="455,35,0,0"
VerticalAlignment="Top"
Width="215"
ItemsSource="{Binding Mode=OneWay}"/>
<ComboBox
x:Name="selEchipamentCombo"
HorizontalAlignment="Left"
Margin="457,65,0,0"
VerticalAlignment="Top"
Width="213"
ItemsSource="{Binding}"/>
code
private void listEchipamente(object sender, SelectionChangedEventArgs e)
{
List<string> echipamenteWCF = client.getEchipament(selClientCombo.Text).ToList();
MessageBox.Show(" Client Selected !");
if (selEchipamentCombo.Items.Count >0)
{
selEchipamentCombo.Items.Clear();
}
for (int i = 0; i < echipamenteWCF.Count(); i++)
{
selEchipamentCombo.Items.Add(echipamenteWCF[i]);
}
}
At the time SelectionChanged is fired, the Text has not been updated (and hence it holds the previous value).
You should access the underlying data item to get the Text instead:
if(selClientCombo.SelectedItem == null) return;
List<string> echipamenteWCF =
client.getEchipament(selClientComo.SelectedItem.ToString()).ToList();
...
I supposed the ToString() will resolve the display Text. You can always cast SelectedItem to the actual type and access its string property (being shown as Text) easily. You can also access the SelectedValue with condition that some SelectedValuePath is set for the ComboBox.

How to save the newly entered item into combobox itemssource?

I am trying to add new item in to Combobox .For ex : if the ComboBox itemssource having "one","two",and "three ". I am able to type by setting IsEditable property to true . New item "Four" which is need to save in combobox . Please share regarding this .
<Window.Resources>
<local:OrderInfoRepositiory x:Key="ordercollection"/>
</Window.Resources>
<ComboBox x:Name="combo" IsEditable="True" ItemsSource="{Binding ComboItems,Source={StaticResource ordercollection}}" Height="50" Width="150"/>
code behind :
void combo_PreviewKeyDown(object sender, KeyEventArgs e)
{
var combo=(sender as ComboBox);
(combo.DataContext as OrderInfoRepositiory).ComboItems.Add(combo.Text);
}
private ObservableCollection<string> comboItems = new ObservableCollection<string>();
public ObservableCollection<string> ComboItems
{
get { return comboItems; }
set
{
comboItems = value;
RaisePropertyChanged("ComboItems");
}
}
public OrderInfoRepositiory()
{
orderCollection = new ObservableCollection<OrderInfo>();
OrderInfoCollection = GenerateOrders();
foreach (OrderInfo o in orderCollection)
{
comboItems.Add(o.Country);
}
}
PreviewKeyDown
Your ComboBox is not bound to the EventHandler comboBox_PreviewKeyDown.
Are you really want to use PreviewKeyDown?
With PreviewKeyDown comboBox.Text still has the Text before excluding your pressed key. Use KeyDown instead.
Each Keypress will add the new and the old typed letters.
Typing "Hello World" will end in H, He, Hel, Hell, etc.
Check for Key.Return to add the Item on completion or use a button. Then you can still use the PreviewKeyDown Event.
void combo_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Return)
{
var combo = (sender as ComboBox);
(combo.DataContext as OrderInfoRepository).ComboItems.Add(combo.Text);
}
}
DataContext
You are casting DataContext to OrderInfoRepositiory but there is no assignment in your code.
Add to your ComboBox:
DataContext="{Binding Source={StaticResource ordercollection}}"
Then you can change your ItemsSource:
ItemsSource="{Binding ComboItems}"
I prefer setting OrderInfoRepositiory in my underlying ViewModel, then you do not need the StaticResource and just bind to the property.
<ComboBox x:Name="combo" IsEditable="True" DataContext="{Binding Source={StaticResource ordercollection}}" ItemsSource="{Binding ComboItems}" Height="50" Width="150" KeyDown="combo_PreviewKeyDown"/>

How to Assign ListBox Selected Items to Source Propertey

I want when a user selects one or multiple items that my source property gets updated. I have tried with the binding mode OneWayToSource but this is not helping. Below is the XAML and ViewModel code:
<ListBox x:Name="ItemsListBox" SelectionMode="Multiple" Height="300"
ItemsSource="{Binding ResultSet}"
SelectedItem="{Binding SelectedItems,Mode=OneWayToSource}">
private List<string> _selectedItems;
public List<string> SelectedItems
{
get
{
return _selectedItems;
}
set
{
_selectedModeItems = value;
NotifyPropertyChanged("SelectedItems");
}
}
I have taken the approach by using Attached behaviours and it works , but is there any simpler way?
Your question should be like this.
How to get multiple selected items from the ListBox in WPF with MVVM?
Well, you have the answer from following stackoverflow threads.
link 1
link 2
Simply you can define IsSelected property in your ResultSet view model. Then if you want to get selected items at any point, just get the items which the "IsSelected" property is set to true from the ResultSet.
you could also create an Attached Behavior
here is an Example how to do it
WPF ListBox has two properties related to the currently selected item:
SelectedItem available for binding, bound to the first selected item.
SelectedItems (with an 's' at the end) is not available to binding.
When multi selection is enabled, you want to have access to SelectedItems but unfortunately you can't bind to it
You can workaround this limitation using code behind.
Create a property named SelectedItems that will contain the selection, then subscribe the SelectionChanged event:
<ListBox x:Name="ItemsListBox" SelectionMode="Multiple" Height="300"
ItemsSource="{Binding ResultSet}"
SelectionChanged="ListBox_SelectionChanged">
private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
foreach (string item in e.RemovedItems)
{
SelectedItems.Remove(item);
}
foreach (string item in e.AddedItems)
{
SelectedItems.Add(item);
}
}

Getting item from Observable Collection or List()

I have a ListBox called NotesList. I have an ObservableCollection called noteList, and I have a TextBox called NoteContents.
In my ObservableCollection, I set the Filename and Contents properties for a few items and then it gets added (bound) to my ListBox.
But now, I want to (when I click a button), show the "Contents" of the ListBox Item that was selected in the NoteContents TextBox.
How can I do this?
I currently have:
private void NotesList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
NoteContents.Text = noteList.Where(x => x.Filename.Contains(NotesList.SelectedValue.ToString())).FirstOrDefault().Contents;
}
You can do this without button clicks, just binding like:
<ListBox Name="NotesList" ItemsSource="{Binding YourObservableCollection}">
<!--Your bindings here-->
</ListBox>
<TextBox Text="{Binding ElementName=NotesList, Path=SelectedItem.Contents}" />

Categories

Resources