I'm trying to initiate an action based on a selection in a ComboBox I created in WPF. I'm pretty new to WPF and C#. My ComboBox has
<ComboBox x:Name="SampleComboBox" Width="100" ItemsSource="{Binding Path=NameList}" />
Where NameList is a List property in the code behind. Now I want to generate an action based on the selection in the ComboBox and not sure where to start. Thanks.
You'll need to add a method to handle the SelectionChanged event. You can either do this in code:
this.MyComboBox.SelectionChanged += new SelectionChangedEventHandler(OnSelectionChanged);
or in XAML:
<ComboBox x:Name="SampleComboBox" Width="100"
ItemsSource="{Binding Path=NameList}" SelectionChanged="OnSelectionChanged" />
where you can then do something with the selected items:
private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
ComboBoxItem cbi = (ComboBoxItem) (sender as ComboBox).SelectedItem;
}
You can get the selected object by writing SampleComboBox.SelectedItem.
This will return an instance of an item in your source list.
Are these a finite set of values in this NameList that is the ItemsSource for this?
Why not amend that xaml to read:
<ComboBox x:Name="SampleComboBox" Width="100" SelectedItem="{Binding TheItem}" ItemsSource="{Binding Path=NameList}" />
and then in your ViewModel for this, have something like:
public static readonly DependencyProperty TheItemProperty=
DependencyProperty.Register("TheItem", typeof(string), typeof(OrderEditorViewModel),
new PropertyMetadata((s, e) => {
switch (e.NewValue) {
case "SomeValue":
// Do something
break;
case "SomeOtherValue":
// Do another thing
break;
default:
// Some default action
break;
}
}));
public string TheItem{
get { return (string)GetValue(TheItemProperty); }
set { SetValue(TheItemProperty, value); }
}
You can do your actions based on the selection in that switch statement which will be invoked whenever the selection is changed.
Related
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.
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"/>
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" );
}
I'm using Caliburn Micro on a Windows Store App.
I have a ListView which has a SelectedItem that works the first time I use it. However, when I clear the ListView and re-bind it to another Collection, the selected item no longer appears selected.
The selectedItem property is being set correctly, since I can hit the breakpoint, and everything works has expected, just the View is not being updated with the selected item, after I clear the collection.
What could be wrong?
Thanks.
Edit:
View Code:
<ListView x:Name="DetailNotes"
ItemsSource="{Binding DetailNotes}"
SelectedItem="{Binding SelectedDetailNote}"
ItemTemplate="{StaticResource Notes600ItemTemplate}"
IsItemClickEnabled="True"
caliburn:Message.Attach="[Event ItemClick] = [DetailNoteSelected($eventArgs)]"/>
ViewModel Code:
(...)
private Note selectedDetailNote;
public Note SelectedDetailNote
{
get { return this.selectedDetailNote; }
set
{
this.selectedDetailNote = value;
this.NotifyOfPropertyChange(() => this.SelectedDetailNote);
}
}
(...)
public void DetailNoteSelected(ItemClickEventArgs eventArgs)
{
Note n = (Note)eventArgs.ClickedItem;
this.SelectedDetailNote = n;
}
Sorry! The problem was my explicit binding. I just left Caliburn do his work, and now it works!
Solution below:
View Code:
<ListView x:Name="DetailNotes"
ItemTemplate="{StaticResource Notes600ItemTemplate}"/>
ViewModel Code:
private Note selectedDetailNote;
public Note SelectedDetailNote
{
get { return this.selectedDetailNote; }
set
{
this.selectedDetailNote = value;
this.NotifyOfPropertyChange(() => this.SelectedDetailNote);
}
}
I know it's late, but your problem was binding mode. You should set it to TwoWay:
SelectedItem="{Binding SelectedDetailNote, Mode=TwoWay}"
In WinRT XAML default is OneWay.
May be I missed something, but I've already beat my head with this one.
I have defined CollectionViewSource:
<CollectionViewSource x:Key="packagesViewSource" d:DesignSource="{d:DesignInstance my:Package, CreateList=True}" />
and ListBox:
<ListBox Name="lstbPackages"
SelectionChanged="lstbPackages_SelectionChanged"
ItemsSource="{Binding Source={StaticResource packagesViewSource}}"
DisplayMemberPath="Name"
SelectedValue="{Binding Path=PackageId, UpdateSourceTrigger=Explicit}"
SelectedItem="{Binding Path=Package}"
SelectedValuePath="IdPackage"
/>
Also, I have code-behind packagesViewSource initialization:
private IQueryable<Packages> GetPackagesQuery()
{
IQueryable<Package> query = dc.PackagesList;
// Returns an ObjectQuery.
return query;
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
...
packagesViewSource =((System.Windows.Data.CollectionViewSource)(this.FindResource("packagesViewSource")));
queryPackages = this.GetPackagesQuery();
packagesViewSource.Source = queryPackages.ToList();
...
}
And the line
packagesViewSource.Source = queryPackages.ToList();
involves event
private void lstbPackages_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
...
}
and as you could guess
lstbPackages.SelectedItem != null
there.
What I do wrong?
Try adding the following to your ListBox xaml.
IsSynchronizedWithCurrentItem="false"
when you assign a source to your ListBox, a DefaultView of your packagesViewSource CollectionViewSource is created. and it has first element selected. So when assigning the source, do it in 3 step:
Get DefaultView for your resource, then
MoveCurrentToPosition(-1) on this view, then
assign the View with correct current position to ListBox.