Getting Listbox Item Index from Button Click - wpf

So I'm using a button in the DataTemplate of my Listbox ItemTemplate. Any ideas how I would grab the index of the item of the Listbox from the button click? I can't see to grab the button's parent.
<ListBox.ItemTemplate>
<DataTemplate DataType="{x:Type local:Img}">
<Button Click="lstButton_Click">...

private void lstButton_Click(object sender, RoutedEventArgs e)
{
Button button = sender as Button;
int index = _myListBoxName.Items.IndexOf(button.DataContext);
//or try this
index = _myListBoxName.ItemContainerGenerator.IndexFromContainer(button.DataContext);
}

You could add a Index property in your view model and set it when you add the view model object into your collection. And then you can access it in your event handler.
private void lstButton_Click(object sender, RoutedEventArgs e)
{
Img t = (sender as Button).DataContext as Img
//Access t.Index here
}

Related

mahapps SplitButton expand on click

I defined a SplitButton in WPF(C#) with a binded item source.
The item list will be expanded only when the user clicks on the arrow at the right of the SplitButton.
How to expand the list when the user clicks on the SplitButton area?
I tried to handle the click event and set the property IsExpanded=true, but it automatically disappears after one second.
<Controls:SplitButton Name="SplitButton_Test"
Width="100"
HorizontalAlignment="Left"
HorizontalContentAlignment="Left"
ItemsSource="{Binding Dictionary_Test}"
DisplayMemberPath="Value"
SelectedValuePath="Key"
Click="Test_Click">
<Controls:SplitButton.Icon>
<iconPacks:PackIconMaterial Margin="6" Kind="Alert" />
</Controls:SplitButton.Icon>
</Controls:SplitButton>
private void Test_Click(object sender, RoutedEventArgs e)
{
if (SplitButton_Test.IsExpanded == false)
{
e.Handled = true;
SplitButton_Test.IsExpanded = true; //Doesn't work, closes automatically after 1 second
}
}
This code in MahApps is closing it:
//Make popup close even if no selectionchanged event fired (case when user select the save item as before)
void ListBoxPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var item = ContainerFromElement(_listBox, e.OriginalSource as DependencyObject) as ListBoxItem;
if (item != null)
{
IsExpanded = false;
}
}
currently at https://github.com/MahApps/MahApps.Metro/blob/develop/src/MahApps.Metro/MahApps.Metro.Shared/Controls/SplitButton.cs#L339
You need to remove that event handler. How? That's whole other question.

Button on ListBox Item

I have a ListBox filled with items. Some of the items may have buttons or links within RichTextBlock inside. I want to fire different action either when the item is pressed or when the button is pressed. The problem is when I hit the button, also the action connected with the item itself is fired. How can I prevent fireing the event of list item when the button inside is pressed?
ListBox:
<ListBox x:Name="StripesList" SelectionChanged="StripesList_SelectionChanged">
</ListBox>
ListBox Items:
<Border x:Name="OuterBorder" Width="400">
<Image x:Name="ThumbnailBox" Width="100" Source="{Binding Thumbnail}" Tap="ThumbnailClick" />
</Border>
Code:
private void StripesList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (StripesList != null)
{
StripesList.SelectedIndex = -1;
}
}
private void ThumbnailClick(object sender, System.Windows.Input.GestureEventArgs e)
{
Image image = sender as Image;
// handle image click
}
private void ItemClick(object sender, EventArgs e)
{
// handle item click
}
I register item click event observers from code behind:
item.Tap += new EventHandler(ItemClick);
set e.Handled=true in the handler of all events . It will stop the Bubbleing of the event.

WPF contextMenu click issue

A ListBox and a ContextMenu are created dynamicaly. The ListBox has some items.
How do I know the ListBoxItem Text that right mouse button clicked on?
private void Init2()
{
ContextMenu contextMenu = new ContextMenu();
MenuItem menuItemOpen = new MenuItem();
menuItemOpen.Click += new RoutedEventHandler(menuItemOpen_Click);
contextMenu.Items.Add(menuItemOpen);
listBox1.ContextMenu = contextMenu;
}
void menuItemOpen_Click(object sender, RoutedEventArgs e)
{
//How do I know the listItem text that right mouse button clicked on?
}
When you right click, you actually also select. So that means you can just do:
private void MenuItem_Click(object sender, RoutedEventArgs e)
{
string selectedListBoxItemText = ((ListBoxItem)listBox1.SelectedItem).Content.ToString());
// do your thing
}

How to automatically select a WPF ListViewItem

I have a ListView in my WPF UserControl using an ItemTemplate to display the items. Within the template is a button. When I select one item and then click on the button of another item, the previously selected item is still selected. I wonder how to automatically select the item the button is in when the button is clicked.
Xaml
<UserControl.Resources>
<DataTemplate x:Key="ItemTemplate">
<Border>
<Grid>
<!-- lots of stuff go here -->
<Button Click="MyButton_Click">Clickme</Button>
</Grid>
</Border>
</DataTemplate>
</UserControl.Resources>
<ListView x:Name="_listView"
ItemTemplate="{StaticResource ItemTemplate}">
</ListView>
C# Code behind
void MyButton_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show( string.Format( "clicked on {0}",
this._listView.SelectedItem.ToString() ) ) ;
}
I would do it by getting the data context of the sender object. Assuming your listview is a list of objects of type MyObject... then something like this would allow you to reference the selected object.
void MyButton_Click(object sender, RoutedEventArgs e)
{
Button b = sender as Button;
if (b == null)
{
return;
}
MyObject o = b.DataContext as MyObject;
if (o != null)
{
// Put stuff for my object here
}
}
When you press the button your click / mouse down event is handled by the button and therefore does not route through to the ListView control.
A possible way to solve this is to manually set the listview.SelectedItem in the button click event.

How to add a focus style to an editable ComboBox in WPF

I've been looking at the following example on how to style the ComboBox, but I haven't been able to create a focus effect when going into an editable combo box. Whenever the ComboBox receives focus, it should go into edit mode and the component should have a focus style.
The basic problem is that whenever I go into the edit mode, it's not the surrounding ComboBox which actually has the focus, but the text subcomponent and I haven't been able to create a Trigger on the text component which modifies the ComboBox's border style since I don't know how to refer to the parent component from the trigger.
I've tried adding ControlTemplate Trigger on the TextBox, or style trigger. I've tried to refer to the ComboBox by name or by using the TemplateBinding option, but without any luck. A simple example would be very appreciated.
Bind IsKeyboardFocusWithin to IsDropDownOpen
<ComboBox ItemsSource="{Binding SortedItems}"
StaysOpenOnEdit="True"
IsDropDownOpen="{Binding IsKeyboardFocusWithin, RelativeSource={RelativeSource Self}, Mode=OneWay}" />
private void cmbSpecialHandling_GotFocus(object sender, RoutedEventArgs e)
{
Thickness th = new Thickness(2);
cmbSpecialHandling.BorderThickness = th;
cmbSpecialHandling.BorderBrush = this.FindResource("TabFocusColor") as SolidColorBrush;
}
private void cmbSpecialHandling_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
Thickness th = new Thickness(2);
cmbSpecialHandling.BorderThickness = th;
cmbSpecialHandling.BorderBrush = this.FindResource("TabFocusColor") as SolidColorBrush;
}
private void cmbSpecialHandling_LostFocus(object sender, RoutedEventArgs e)
{
cmbSpecialHandling.BorderBrush = Brushes.Transparent;
}
Set the border brush of combobox in its Gotfocus and make it transparent in lost focus:
private void comboBox_GotFocus(object sender, RoutedEventArgs e)
{
Thickness th = new Thickness(2);
comboBox.BorderThickness = th;
comboBox.BorderBrush = this.FindResource("TabFocusColor") as SolidColorBrush;
or
comboBox.BorderBrush = Brushes.Green;
}
private void comboBox_LostFocus(object sender, RoutedEventArgs e)
{
comboBox.BorderBrush = Brushes.Transparent;
}

Resources