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.
Related
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.
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 would like to get the current index of an item in a listbox that was added dynamically. Essentially my item is a HubTile, and hubtiles are added on a click event one at a time. The collection of hubtile items are held in an ObservableCollection. This observablecolelction is bound to a listbox which displays the items. To illustrate, what I have is as follows:
TabsPage.xaml
<ListBox x:Name="tileList" Grid.Row="0" Margin="12,0,12,0" toolkit:TiltEffect.IsTiltEnabled="True">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<toolkit:WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<toolkit:HubTile Title="{Binding TileName}" Margin="6"
Notification="{Binding Notification}"
DisplayNotification="{Binding DisplayNotification}"
Message="{Binding Message}"
GroupTag="{Binding GroupTag}"
Source="{Binding ImageUri}"
Tap="hubTile_Tap">
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu x:Name="menu">
<toolkit:MenuItem Header="pin to start" Tap="MenuItem_Tap"/>
<toolkit:MenuItem Header="delete" Tap="deleteMenuItem_Tap"/>
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
</toolkit:HubTile>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
TabsPage.xaml.cs
ObservableCollection<TileItem> tileItems;
public TabsPage()
{
InitializeComponent();
CreateTileList(); //starts the list of HubTiles with a single main tile
}
private void CreateTileList()
{
tileItems = new ObservableCollection<TileItem>()
{
//TileItem is
new TileItem() { ImageUri = mainImage, Title = "main", /*Notification = "",*/ Message = "main", GroupTag = "MainGroup", TileName = "main" },
};
//Set the first tile item
this.tileList.ItemsSource = tileItems; //sets the tileList Listbox ItemsSource to the tileItems ObservableCollection
}
void addNew_Click(object sender, EventArgs e)
{
BitmapImage newTileImage = new BitmapImage();
var newItem = new TileItem() { ImageUri = newTileImage, Title = "new", /*Notification = "",*/ Message = "new HubTile", GroupTag = "TileGroup", TileName = "new" };
tileItems.Add(newItem); //update UI immediately and add to collection
}
private void hubTile_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
//how to get the current index of the tapped HubTile//
//var tap = (((sender as HubTile).Parent as ListBox).SelectedIndex); //NullReferenceException thrown
}
So, the HubTile items are correctly added to the UI, but on the tapped event I do not know how to get the selected index of the currently tapped HubTile item?
You can use the DataContext of the item clicked like such
private void hubTile_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
FrameworkElement element = (FrameworkElement)sender;
TileItem item = (TileItem)element.DataContext;
int index = tileItems.IndexOf(item);
// Use the index
}
You can also subscribe to the SelectionChanged event of the ListBox instead of the Tap event of the Hubtile. Then in the Selectionchanged event you can get the index.
private void OnSelectionChanged(object sender, SelectionChangedEventArgs selectionChangedEventArgs)
{
int index = tileList.SelectedIndex;
}
Make the tileItems a public property and bind to it in XAML it as the source.
Add a public int and bind the path to it as the SelectedIndex
<ListBox ItemsSource="{Binding Path=Rules}" SelectedIndex="{Binding Path=SelectedIndex, Mode=TwoWay}">
i am working with wpf media element.i want to change the media element source according to listbox item.
i created next button when clicking the next buton ,listbox item changed to next item.i dont know how to change the media element source to next listbox item when clicking the next button..
can any one have idea on this.
plz help me.thanks in advance....
my .xaml file...
<MediaElement Margin="7,29,80,6" Name="mediaElement1" LoadedBehavior="Manual"
AllowDrop="True" MediaOpened="mediaElement1_MediaOpened"
Grid.IsSharedSizeScope="False" ScrubbingEnabled="True" IsEnabled="True"
Stretch="Fill" Drop="mediaElement1_Drop" ClipToBounds="False"
Visibility="Visible" OpacityMask="DarkRed" BufferingStarted="btn_play_click"
MediaEnded="mediaElement1_MediaEnded"
MouseLeftButtonUp="mediaElement1_MouseLeftButtonUp" Grid.Row="1" />
<ListBox Margin="0,31,0,18" Name="listBox1" HorizontalAlignment="Right" Width="74"
Grid.Row="1" MouseDoubleClick="listBox1_MouseDoubleClick" SelectedIndex="0"
SelectionMode="Multiple" AllowDrop="True"> </ListBox>
my next button code in .cs file is
private void btn_next_Click(object sender, RoutedEventArgs e){
listBox1.SelectedIndex = listBox1.SelectedIndex + 1;
mediaElement1.Source = new System.Uri(listBox1.SelectedValue as string);
}
Use SelectedItem instead of SelectedValue, or also set SelectedValuePath:
private void btn_next_Click(object sender, RoutedEventArgs e)
{
listBox1.SelectedIndex = listBox1.SelectedIndex + 1;
mediaElement1.Source = new System.Uri(listBox1.SelectedItem as string);
}
If you added ListBoxItems to the ListBox you would have to get their Content:
private void btn_next_Click(object sender, RoutedEventArgs e)
{
listBox1.SelectedIndex = listBox1.SelectedIndex + 1;
ListBoxItem item = listBox1.SelectedItem as ListBoxItem;
mediaElement1.Source = new System.Uri(item.Content as string);
}
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;
}