I have a form with two listboxes, listbox1 & listbox2. On form load I am filling up both the list boxes with same no. of items.
I want that if I select item at index 1 in listbox1 then in listbox2 item with the same index should also be selected.
How do I achieve this?
Subscribe on both listboxes SelectionChanged event and then set the SelectedIndex accordingly for the opposite listbox.
You can bind SelectedIndex in listBox2 to the SelectedIndex in listBox1.
Like so:
<ListBox Name="listBox1" />
<ListBox SelectedIndex="Binding ElementName=listBox1,Path=SelectedIndex" />
However, if you want to reflect the selection change on the listBox2 back to listBox1, you can't just do the same binding in listBox1, because it will throw StackOverflowException. You should subscribe to the SelectionChanged event on listBox2 and change the SelectedIndex of listBox1 in code.
Like so:
<ListBox Name="listBox2" SelectedIndex="Binding ElementName=listBox1,Path=SelectedIndex" SelectionChanged="listBox2_SelectionChanged" />
And the event handler method looks like this:
private void listBox2_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
listBox1.SelectedIndex = listBox2.SelectedIndex;
}
Related
I would like to know how to trigger the selectionChange event of a combobox only when the user himself change the selection of the list. (Avoid other cases) I found a solution here but I have some errors. Could you help me?
https://msdn.microsoft.com/en-us/library/system.windows.forms.combobox.selectionchangecommitted(v=vs.110).aspx
I added System.Windows.Forms in my .cs file and it says there is an ambiguity beetween 'System.Windows.Controls.ComboBox' and 'System.Windows.Forms.ComboBox' with the first line of the code below.
I dont know how to cast my sender into a comboBox.
ComboBox senderComboBox = (ComboBox)sender;
if (senderComboBox.SelectionLength > 0)
{
//code here
}
Thanks for help!
You are trying to reference WinForms ComboBox and not WPF ComboBox. You can listen to SelectionChanged event of the control to know when user changes the selection.
A sample code from dotnetperls
XAML
<ComboBox
HorizontalAlignment="Left"
Margin="10,10,0,0"
VerticalAlignment="Top"
Width="120"
Loaded="ComboBox_Loaded"
SelectionChanged="ComboBox_SelectionChanged"/>
CS File
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
// ... Get the ComboBox.
var comboBox = sender as ComboBox;
// ... Set SelectedItem as Window Title.
string value = comboBox.SelectedItem as string;
this.Title = "Selected: " + value;
}
This sort of approach worked for me - XAML ComboBox SelectionChanged Fires OnLoad
Basically only wire-up the ComboBox_SelectionChanged event after the form has loaded - this will get you around the programmatic change that will fire onload. Beyond that I'm not sure. It might be that you need to use a different event, but I haven't looked into this.
I'm assuming this is a simple thing that I am missing.
I have a ListBox in a WPF app that I am writing. Each row has a button to perform a simple action based on the row that the button is on. If the user clicks on the button directly then the SelectedItem on the ListBox is null. If I click in the row first, then click the button the SelectedItem is the row, as expected.
I want to be able to have the row that the button is on selected when the button is clicked. Again, I'm assuming that I am missing something simple, but my searches are coming up empty so far.
In case you want to select ListBoxItem on button click of ListBoxItem you can do this by attaching click handler to your button.
Assuming you have this XAML for ListBox declaration:
<ListBox x:Name="listBox" ItemsSource="{Binding SourceCollection}">
<ListBox.ItemTemplate>
<DataTemplate>
<Button Content="{Binding PropertyName}" Click="Button_Click"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
you can select listBoxItem from handler:
private void Button_Click(object sender, RoutedEventArgs e)
{
ListBoxItem selectedItem = (ListBoxItem)listBox.ItemContainerGenerator.
ContainerFromItem(((Button)sender).DataContext);
selectedItem.IsSelected = true;
}
Access DataContext of button which will be same as that of ListBoxItem. Hence, with it you can get container element i.e. ListBoxItem from ItemContainerGenerator.
Set IsSelected to True on fetched listBoxItem.
I have a listbox that, when an item is selected, invokes a method that executes a Stored Procedure.
The problem is that when the first item is selected, my PropertyChanged event doesn't fire unless the selection is changed from one item to another. Thus the second item SelectedItem PropertyChanged notification is fired, but it looks like selecting the first item is just seen as entering the listbox, instead of entering the listbox AND selecting the item the click occurs on.
Also, I can't just click twice on the same item to get the notification to fire, I have to actually select a different property for the event to occur.
What is the best way to get the item I first click on upon entering the listbox to be the SelectedItem, having the PropertySelected/Property Changed event firing on this item? I hope this is clear.
Below is my code, thanks in advance!
In my viewmodel:
public ObjectClass SelectedObject
{
get { return _SelectedObject; }
set
{
_SelectedObject = value;
base.OnPropertyChanged("SelectedObject");
}
}
void OnPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case "SelectedObject" : UpdateSelectedStuffList.StoredProcedureMethod(this);
}
}
In my view:
<ListBox ItemsSource="{Binding Path=ObjectCollection, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
DisplayMemberPath="objectName"
SelectedItem="{Binding Path=SelectedObject, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
I was thinking that instead of using PropertyChangedEventArgs, there would be something like "PropertySelectedEventArgs." OR, maybe I need to implement INotifyPropertyChanging?
If you want this to fire even if you select the same item twice in a row, I would look at OnClick. Otherwise, consider setting the selected index to -1 so that when the first item is selected by the user, it will have a changed value.
What event do I have to listen for, to get notified when a user selects an option from a (editable) WPF ComboBox control?
Do I have to access the Items property first to then listen to Items.CurrentChanged? And if so, how do I add that listener in XAML?
How about the SelectionChanged event?
EDIT: Added a simple example
<ComboBox SelectionChanged="ComboBox_SelectionChanged"/>
and in code-behind:
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
}
if you are looking to do it in MVVM then its:
<ComboBox SelectedItem={Binding Path=SelectedItem}/>
assuming you have a SelectedItem property in your ViewModel set to the proper objectType.
I am writing a windows-phone 7 application. I've got a page with a list of TextBlock(s) contained in a ListBox. The behavior I want is that upon clicking one of those TextBlock(s) the page is redirected to a different one, passing the Text of that TextBlock as an argument.
This is the xaml code: (here I am binding to a collection of strings, and the event MouseLeftButtonDown is attached to each TextBlock).
<ListBox x:Name="List1" ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock MouseLeftButtonDown="List1_MouseLeftButtonDown" Text="{Binding}"
FontSize="20"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
But this has been unsuccessful for me. I have tried attaching MouseLeftButtonDown event to either the individual TextBox(es) or to the ListBox. And I have had exceptions raised as soon as I use NavigationService.Navigate(uri). Which event should be attached? Should the event be attached to the individual items or to the list as a whole?
I have found a way to work around this problem by populating ListBox with HyperlinkButton(s). However, I would like to understand why the TextBox approach did not work.
This is my first attempt with Silverlight, so I might be missing something basic here.
There are a few ways to do this but I'll walk you through one of the the simplest (but not the purest from an architectural perspective).
Basically you want to find out when the selection of the ListBox changes. The ListBox raises a SelectionChanged event which can be listened to in the code behind.
<ListBox x:Name="List1" ItemsSource="{Binding}" SelectionChanged="SelectionChangedHandler" SelectionMode="Single" >
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" FontSize="20"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Then have a handler something like:
private void SelectionChangedHandler(object sender, SelectionChangedEventArgs e)
{
IList selectedItems = e.AddedItems;
string val = selectedItems.OfType<string>().FirstOrDefault();
NavigationService.Navigate(new Uri(val));
}
One thing you'll need to be aware of is that ListBoxes support multiple selection. For this reason, the event arguments give you back a list of the selected items. For simplicity, all I've done is taken the first value from this list and used that as the navigation value. Notice how I've also set the SlectionMode property of the ListBox to Single which will ensure the user can only select one item.
If I were doing this for real I'd look into creating an TriggerAction tat can be hooked up to an event trigger through xaml which will remove the for code behinds. Take a look at this link if you're interesetd.
In addition to Chris' and James' replies, I'd add that you will also need to clear the listbox selection in the event handler, otherwise the user won't be able to tap the same item twice on the listbox (because the item will already be selected).
Using James' approach, I would change the SelectionChangedHandler() implementation as follows:
private void SelectionChangedHandler(object sender, SelectionChangedEventArgs e)
{
// Avoid entering an infinite loop
if (e.AddedItems.Count == 0)
{
return;
}
IList selectedItems = e.AddedItems;
string val = selectedItems.OfType<string>().FirstOrDefault();
NavigationService.Navigate(new Uri(val));
// Clear the listbox selection
((ListBox)sender).SelectedItem = null;
}
What I would recommend is binding the SelectedItem property of the ListBox to a property in your ViewModel. Then, on the ListBox's SelectedItemChanged event, navigate to to the appropriate URL passing the data key on the QueryString, or upgrade to something like MVVM Light and put the actual SelectedItem object on the message bus for the child window to pick up. I have a sample of this second method on my Skydrive that you can check out.
HTH!
Chris