I have list of items in LongListMultiSelector - how to handle a selected item?
My LongListMultiSelector xaml:
<tkit:LongListMultiSelector Name="longlist" SelectionChanged="longlist_SelectionChanged">
<tkit:LongListMultiSelector.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Title}" FontSize="32" Tap="TextBlock_Tap"/>
</DataTemplate>
</tkit:LongListMultiSelector.ItemTemplate>
</tkit:LongListMultiSelector>
TextBlock tap event handler code:
private void TextBlock_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
var itemTapped = (sender as FrameworkElement).DataContext as Book;
}
LongListMultiSelector SelectionChanged event handler code:
private void longlist_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
}
I found part of solution here, however, The problem if at least one item is selected, then textblockTap event doesn't handle - longlist_SelectionChanged event handles everything. How can i fix that?
Once you are using LongListMultiSelector, the SelectionChanged event is fired when item is added or removed. If you want to perform the action regardless item is added/removed, I've managed to do it like this (for a simle string):
private void longlist_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
string selectedItem = String.Empty;
if (e.AddedItems.Count > 0) selectedItem = e.AddedItems[0] as string;
else selectedItem = e.RemovedItems[0] as string;
MessageBox.Show(selectedItem); // do your work
}
It should run while items are selected separately by tapping, but this method will have problems when more items are added/removed at the same time - if you need it, then you should handle this also.
Your XAML DataTemplate.
<DataTemplate x:Key="listItemTemplate">
<StackPanel Orientation="Horizontal" Margin="4,4">
<TextBlock Tap="textblockTap" Margin="0,-7,0,0" Text="{Binding Name}" Style="{StaticResource PhoneTextLargeStyle}"/>
</StackPanel>
</DataTemplate>
In your CS page;
private void textblockTap(object sender, EventArgs e)
{
var file = (TextBlock)sender;
var ContentFile = (string)file.Text;
MessageBox.Show(ContentFile);
}
This example will show you the text of the selected item in the MessageBox.
Related
I have a ListBox in app, it has an image and textbox inside. I want to set 2 colors and 3rd one for selected item.
<ListBox.ItemTemplate>
<DataTemplate x:Name="Template1">
<StackPanel Orientation="Horizontal" >
<Image Width="100" Height="100" Source="{Binding SmallImage}"></Image>
<Grid>
<TextBlock Text="{Binding Caption}" Foreground="{Binding txtColor}"></TextBlock>
</Grid>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
when I'm changing the foreground color, then the selected item doesn't highlights (I kept it by default).
I tried to add an event to ListBox,
private void DList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ListBoxItem selectedItem = DList.SelectedItem as ListBoxItem;
selectedItem.Foreground = new SolidColorBrush(Colors.Red);
}
but it shows an exception:
NullReferenceException
"Use the "new" keyword to create an object instance"
If you're going to handle the SelectionChanged event, then you might as well use the SelectionChangedEventArgs object:
private void DList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var selectedDataObject = e.AddedItems[0]; // assuming single selection
ListBoxItem selectedItem =
ListBoxName.ItemContainerGenerator.ContainerFromItem(selectedDataObject);
selectedItem.Foreground = new SolidColorBrush(Colors.Red);
}
I created a ListBox with ListBoxItems and add an MouseDown event handler to each of the ListBoxItems. The ListBoxItems are shown, but when I click on a ListBoxItem, the Event doesn't get fired.
How i set the MouseUp:
TrackedProcessList.ItemsSource = null;
TrackedProcessList.ItemsSource = this.tracks;
/*... some other code that doesn't matter ... */
ListBoxItem[] items = new ListBoxItem[TrackedProcessList.Items.Count];
for (int i = 0; i < TrackedProcessList.Items.Count; i++)
{
Object obj = TrackedProcessList.Items.GetItemAt(i);
//TrackedProcessList.UpdateLayout();
ListBoxItem item = (ListBoxItem)(TrackedProcessList.ItemContainerGenerator.ContainerFromIndex(i));
if (item != null)
{
item.MouseUp += new MouseButtonEventHandler(ListBoxItem_MouseUp_PostQuestion);
items[i] = item;
}
}
The Method which should be called (but it isn't):
private void ListBoxItem_MouseUp_PostQuestion(object sender, EventArgs e)
{
MessageBox.Show("ListBoxItem_MouseUp_fired");
}
My XAML:
<ListBox x:Name="TrackedProcessList" Height="145" Width="605" ItemsSource="{Binding}" BorderThickness="1,0" IsSynchronizedWithCurrentItem="True">
<DataTemplate>
<TextBlock MouseDown="ListBoxItem_MouseUp_PostQuestion" Text="{Binding Path=programName}" HorizontalAlignment="Stretch" ></TextBlock>
</DataTemplate>
</ListBox>
Do you have any ideas where the failure could be? There is no error. The Event just seems to be not bound to the ListBoxItem.
It is because ListBoxItem already handles both left and right click which means your event handler will not be triggered according to WPF routed event rules. Your either have to assign PreviewMouseDown event or add event handler for handled events:
lbi.AddHandler(ListBoxItem.MouseDownEvent, new MouseButtonEventHandler(MouseEvent), true);
void OnListBox_Mouse_Down(object sender, MouseButtonEventArgs e)
{
e.Handled
}
void OnListBox_Mouse_Up(object sender, MouseButtonEventArgs e)
{
"Do Something";
}
Use the ContainedControl property and set your events :)
kryptonListBox1.ContainedControl.MouseDown += kryptonListBox1_MouseDown_1;
I'm writing a Windows Store app and I need a ComboBox to have its default value. I also would like to know which item from the list the user selects but I can't find out how to do it. I tried different properties but with no results. Any ideas about doing this?
The code I have for create the ComboBox is:
<ComboBox x:Name="cboxelemento" Width="350" ItemsSource="{Binding}"
SelectionChanged="cboxelemento_SelectionChanged">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock x:Name="lnombre" Text="{Binding Nombre}" FontSize="24"/>
</DataTemplate>
</ComboBox.ItemTemplate>
<ComboBox.DataContext>
<Clases:Datos/>
</ComboBox.DataContext>
</ComboBox>
private void cmbox_SelectedValueChanged(object sender, EventArgs e)
{
var val = cmbox.SelectedValue;
//or
//cmbox.Selectedindex;
}
you can access the value like this
First you must use the SelectedValueChanged Event.
private void cmbox_SelectedValueChanged(object sender, EventArgs e)
{
if (cmbox.Focused)
{
//do
}
}
The property Focused goes to true when you have clicked on the ComboBox.
for example, i have a simple database (int id, string text) and listbox.
in each listbox element i have a textblock, image and button.
when I add items I want each item listobox was known as the id.
When I click the button, the id is passed in another form in which I can edit the database post.
page.xaml
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<Image Source="{Binding IconSource}"/>
<StackPanel>
<TextBlock Text="{Binding Text}"/>
<Button Click="Edit_Click1"></Button>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
page.xaml.cs
private void Edit_Click1(object sender, RoutedEventArgs e)
{
int id = 0; // i want to know id of current element of listbox
NavigationService.Navigate(new Uri("/EditTask.xaml?currentID="+id, UriKind.Relative));
}
how i can name current item of listbox and then know name of this element? sorry for horrible english.
You can access the listbox.SelectedItem to get the selected item:
private void Edit_Click1(object sender, RoutedEventArgs e)
{
int id = (listbox.SelectedItem as MyClass).Id;
NavigationService.Navigate(new Uri("/EditTask.xaml?currentID="+id, UriKind.Relative));
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var button = ((System.Windows.Controls.Button)sender);
var clickedItem = (DataItem)button.DataContext;
MessageBox.Show(clickedItem.Name);
}
Here I'm asuming DataItem is the name of the class that represents each item.
i have a listbox with a data template that contains a button.
When the button is clicked I want to get in the button
click handler the index of the listbox item that was current??
How do I do this please?
Malcolm
More appropriate answer,
private void Button_Click(object sender, RoutedEventArgs e)
{
DependencyObject dep = (DependencyObject)e.OriginalSource;
while ((dep != null) && !(dep is ListViewItem))
{
dep = VisualTreeHelper.GetParent(dep);
}
if (dep == null)
return;
int index = lstBox.ItemContainerGenerator.IndexFromContainer(dep);
}
Hope the bellow code will help you.
private void Button_Click(object sender, RoutedEventArgs e)
{
var b = (Button)sender;
var grid = (Grid)b.TemplatedParent
var lstItem = (ListBoxItem)grid.TemplatedParent;
int index = lstBox.ItemContainerGenerator.IndexFromContainer(lstItem);
// rest of your code here...
}
And the XAML for the above assumed to be a DataTemplate on a ListBox named lstBox:
<DataTemplate x:Key="template">
<Grid>
<Button Click="Button_Click" Content="Press"/>
</Grid>
</DataTemplate>
Have you checked the "SelectedIndex" property of the listbox? It might be set by clicking on the button.
Probably way to late but using "IndexOf" on the listbox "Items" will give you the index #
Regards
myListbox.Items.CurrentItem seems be what you are looking for.
Hi you can use ContentPresenter.Content to get current item , instead of current index:
<DataTemplate DataType="{x:Type MyModel}">
<StackPanel Orientation="Horizontal" Margin="0 5">
<TextBlock Text="{Binding Title}" />
<Button Content="Active" Click="Button_Click" />
</StackPanel>
</DataTemplate>
and in code:
private void Button_Click(object sender, RoutedEventArgs e)
{
var button = e.Source as Button;
var contentPresenter = button.TemplatedParent as ContentPresenter;
var myModel = (MyModel)contentPresenter.Content;
}