SelectionChanged Combobox WPF - c#

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.

Related

How to update combo box item in wpf?

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>

Unable to reselect single item in listview

I have a listview in WPF in an MVVM/PRISM app which may contain 1-to-many elements. When the listview contains only 1 element, and I select it, I cannot subsequently reselect it even though I set the SelectedIndedx value to -1. Worse, if I make the app update the listview with a different single element, I can't select that one either. The only way I can achieve selection of an item when it is the only item in the listview is to make the app display multiple items and select something other than the first. Then, when I make the app display a listview containing a single item, I can select it again - but only once.
In those cases where I cannot select the single item in the listview, the servicing routine never fires.
I tried implementing a XAML suggestion I found here using "Listview.Container.Style" and the IsSelected property, but that did not work.
My listview is fairly straightforward:
<ListView Name="lstEditInstance"
Grid.Row="5"
ItemsSource="{Binding Path=InstanceList,Mode=TwoWay}"
Width="488"
FontFamily="Arial" FontSize="11"
HorizontalAlignment="Left" VerticalAlignment="Stretch"
Margin="10,96,0,28"
SelectedIndex="{Binding Path=InstanceSelectedIndex}">
</ListView>
The servicing routine is:
private void OnInstanceSelectedIndexChanged()
{
// Handle case where user hits Enter without making a selection:
if (_instanceIndex == -1) return;
// Get the instance record for the row the user clicked on as a
// ResourceInstance class named "InstanceRecord".
InstanceRecord = _instanceList[_instanceIndex];
_instanceNumber = InstanceRecord.Instance;
FormInstName = InstanceRecord.InstName;
FormInstEnabled = InstanceRecord.Enabled;
FormInstState = InstanceRecord.InitialState;
FormInstIPAddress = InstanceRecord.IPAddress;
FormInstPort = InstanceRecord.Port.ToString();
FormInstSelectedURL = InstanceRecord.UrlHandler;
} // End of "OnResourceSelectedIndexChanged" method.
"InstanceList" is an observable collection.
I'd appreciate some suggestions. Thanks in advance for any help.
In a MVVM scenario, I'd use a ViewModel that contains the selected item instead:
class MyViewModel {
private IList<Item> instanceList= new List<Item>();
public IList<Item> List
{
get {return list; }
set {
list = value;
RaisePropertyChanged(() => List);
}
}
private Item selectedItem;
public Item SelectedItem {
get {return selectedItem;}
set {
selectedItem = value;
RaisePropertyChanged(() => SelectedItem);
}
}}
And the XAML:
<ListView Name="lstEditInstance"
Grid.Row="5"
ItemsSource="{Binding Path=InstanceList}"
Width="488"
FontFamily="Arial" FontSize="11"
HorizontalAlignment="Left" VerticalAlignment="Stretch"
Margin="10,96,0,28"
SelectedItem="{Binding Path=SelectedItem, Mode=TwoWay}}">
Notice that observableCollection is not required unless you have to modify the list items, in the same way the binding should be the default one for the list.
The SelectedItem / SelectedIndex should be TwoWay or Onewaytosource, the latter if you think you don't need to change the selectedItem programmatically
The service routine should be called from the ViewModel
EDIT:
your code of the service routine should be placed there:
set {
selectedItem = value;
// your code
RaisePropertyChanged(() => SelectedItem);
}
Another valid approach is to use Blend on XAML, by invoking a command on changed index and process under the ViewModel.
To do this, first add reference to System.Windows.Interactivity in your project and in XAML add
xmlns:interactivity="http://schemas.microsoft.com/expression/2010/interactivity
Then modify ListView with the following:
<ListView Name="lstEditInstance"
Grid.Row="5"
ItemsSource="{Binding Path=InstanceList}"
Width="488"
FontFamily="Arial" FontSize="11"
HorizontalAlignment="Left" VerticalAlignment="Stretch"
Margin="10,96,0,28"
SelectedItem="{Binding Path=SelectedItem, Mode=TwoWay}}">
<interactivity:Interaction.Triggers>
<interactivity:EventTrigger EventName="SelectionChanged">
<interactivity:InvokeCommandAction Command="{Binding YourCommand}"
CommandParameter="{Binding YourCommandParameter}" />
</interactivity:EventTrigger>
</interactivity:Interaction.Triggers>

Accessing ListBox and other children in a LongListSelector

I'm building an app where there's a arbitrarily long list of items where you can click on any of them and edit in place. As you edit any of these items I want to programmatically change focus to the next item in the list.
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<phone:LongListSelector x:Name="MainLongListSelector" Margin="0,0,-12,0" ItemsSource="{Binding Items}" SelectionChanged="MainLongListSelector_SelectionChanged">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,-10,0,-12">
<TextBox x:Name ="tb" Text="{Binding TheText}" TextWrapping="Wrap" TextChanged="TextBox_TextChanged" />
</StackPanel>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
</Grid>
As the user types in the first TextBox and his text exceeds a certain # of characters (e.g. 138) I want to either add another item to the list as the next item and change focus to it, or, if there's already a next item, change focus to it.
I can't figure out how to get access to
1) The root list box
2) The TextBox control within an item given a list box item ID
Here's what I tried. When this runs, the MainLongListSelector.SelectedITem = nextItem causes the next item to be selected, but it does NOT get focus.
private void TextBox_TextChanged(object sender, TextChangedEventArgs e) {
var editBox = sender as TextBox;
var selectedItem = MainLongListSelector.SelectedItem as ItemViewModel;
if (editBox != null && selectedItem != null && editBox.Text.Length > 138) {
// Move data at end to next box
var overflow = editBox.Text.Substring(138, editBox.Text.Length - 138) ;
selectedItem.Tweet = editBox.Text.Substring(0, 138);
var nextItem = App.ViewModel.Items[int.Parse(selectedItem.ID) + 1];
nextItem.Tweet = overflow;
MainLongListSelector.SelectedItem = nextItem;
}
}
I want to be able to access the actual TextBox of that nextItem so I can explicitly set focus to it.
The same question applies if I just use ListBox but the issues are different. In the ListBox case when the DataTemplate contains a TextBox and focus is set, I don't get SelectionChanged events...which is why I'm sticking with LongListSelector.
If I understand you correctly, you want to the TextBox get focus when the item item selected.
If this is what you need, here is a way to bind LisBoxItem.IsSelected To Element.Focus():
http://social.msdn.microsoft.com/Forums/en-US/adeb3e7f-16df-4c7b-b2d2-d7cdedb32ac0/setting-focus-of-a-textbox-inside-a-listbox?forum=wpf

Combobox refresh gives Value '' couldn't be converted validation error

i'm new to WPF. I have an application with multiple tabs. In one tab I can insert data into a table in the database. In another tab I have a combobox with itemsource of the table mentioned earlier. I want to update the combobox items when user want to chose from the combobox./
I tried with the GotFocus property in the following way:
private void ComboBoxOperatingPoints_GotFocus_1(object sender, RoutedEventArgs e)
{
this.ThisViewModel.UpdateModel();
}
Updatemodel function contains the following:
this.OperatingPoints = new ObservableCollection<Operating_Point>(new OperatingPointRepository().GetAll());
this.NotifyPropertyChanged("OperatingPoints");
The combobox bindind in the XAML :
<ComboBox SelectionChanged="ComboBoxOperatingPoints_SelectionChanged"
x:Name="ComboBoxOperatingPoints"
GotFocus="ComboBoxOperatingPoints_GotFocus_1"
FontSize="30"
HorizontalAlignment="Right"
Margin="40,40,0,0"
VerticalAlignment="Top"
Width="200"
Height="50"
IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding OperatingPoints}"
DisplayMemberPath="name"
SelectedValue="{Binding OperatingPointID,UpdateSourceTrigger=PropertyChanged}"
SelectedValuePath="operating_point_id"
>
The combobox refresh, but gives validation error and I can't use it anymore after the first GotFocus event occured.
Thanks in advance!
EDIT:
Finaly I changed the GotFocus event to DropDownOpened event and it's working fine.
Your code is creating a new ObservableCollection on every update. You probably only want to create the ObservableCollection once, then replace it's contents in UpdateModel. So, for example, in your view model's constructor, instantiate the OperatingPoints collection:
public class MyViewModel {
public MyViweModel() {
this.OperatingPoints = new ObservableCollection<Operating_Point>();
}
}
Then, in UpdateModel:
public void UpdateModel() {
this.OperatingPoints.Clear();
foreach ( Operating_Point point in new OperatingPointRepository().GetAll() ) {
this.OperatingPoints.Add(point);
}
NotifyPropertyChanged( "OperatingPoints" );
}

Getting selected item string from bound ListBox

I'm having a problem with getting a string from a bound textblock within a listbox, when I use the code below, I can bind the listbox and the listbox has items showing up, but when the item in the list is clicked I don't get the proper string, I print a message box a message with objects names like
"MyApp.Item"
shows up instead. myApp is the name of the app and Item is the name of my model that I am binding to the listbox. The proper text from the selected item showed up when the listbox was not binded.
private void listBoxtrend_Tap(object sender, GestureEventArgs e)
{
selectedText = "";
selectedText = listBox.SelectedValue.ToString();
MessageBox.Show(selectedText);
}
xml
<ListBox ItemsSource="{Binding Item}" Foreground="RoyalBlue"
Height="395" HorizontalAlignment="Center"
Margin="12,111,0,0" Name="listBox"
VerticalAlignment="Top" Width="438"
TabIndex="10" Tap="listBox_Tap" >
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock TextWrapping="Wrap" FontSize="26" HorizontalAlignment="Left"
Name="tblItem" Text="{Binding ItemString}"
VerticalAlignment="Top" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I'd really appreciate if you could help me thanks
You're binding to the ItemString in the DataTemplate's TextBlock and the Item Collection in the ListView. As such the SelectedValue will be of the Item type. You should actually be doing something like this in your Tap handler to get at the ItemString's value...
private void listBoxtrend_Tap(object sender, GestureEventArgs e)
{
selectedText = "";
var selected = listBox.SelectedValue as Item;
selectedText = selected.ItemString;
MessageBox.Show(selectedText);
}
In your example, the ToString is printing the name of the class. You could also override ToString in your Item model to be whatever you want the string to be.
Note: the types and such may be a bit off, I guessed a bit based off of what you wrote in your question. Also, there is no need to set selectedText to an empty string that will just be overwritten in the third line above. I wanted to keep it so you could get some idea of what I changed in your code.
It's very simple, try following:
string selectedText = ListBox.GetItemText(ListBox.SelectedItem);
You need to also set the SelectedItem of the Listbox to something.
SelectedItem = {Binding SelectedItem}
and rename your ItemsSource to "Items" as that makes more sense.
Your SelectedItem in your codebehind or your ViewModel should then contain a property:
public class Item
{
public string ItemString { get;set; }
}
Try This...
string ListBoxConent = ((ListBoxItem)listbox.SelectedItem).Content.ToString();
Try
listBox.SelectedItem.ToString()
If a property isn't specified in ValueMember then SelectedValue returns the results of the ToString method of the object.

Categories

Resources