How to determine listboxitem a button was pressed from? - c#

Basically I'm dynamically adding items to a listbox. Inside of each listbox item I have also added a button control that will perform a specific action on the item from which the button was clicked.
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Title"/>
<Button Click="MyBtn_Click"/>
</StackPanel>
</DataTemplate>
Does anyone know how to determine which item the button was clicked from? I know each listbox item contains an index. I think if you could access the parent of the button you could then deterimine which button was clicked?

You could use the CommmandParameter of the button to hold a value -
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Title}"/>
<Button Click="MyBtn_Click" CommandParameter={Binding Title}/>
</StackPanel>
</DataTemplate>
public void MyBtn_Click(object sender, args)
{
string MyVal = (sender as Button).CommandParameter.ToString();
}
Convention is to use the Command event instead of the click event for this type of thing.

Related

How can I disable the selection event on this WPF ComboBox without disabling it?

I have the following ComboBox XAML:
<ComboBox Width="350" ItemsSource="{Binding RunSets}" SelectedItem="{Binding SelectedRunSet, Mode=OneWay}" VerticalAlignment="Center" Height="20" Margin="5,1,0,0" Background="DimGray" Foreground="White" >
<ComboBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ComboBox.ItemsPanel>
<ComboBox.ItemTemplate>
<DataTemplate>
<Grid Width="320">
<CheckBox IsChecked="{Binding IsSelected}" Margin="2,2,10,0" Visibility="{Binding ExchangeMarketNamesVisibility}" PreviewMouseDown="RunsetComboBoxItem_PreviewMouseDown">
<CheckBox.Content>
<StackPanel PreviewMouseDown="RunsetComboBoxItem_PreviewMouseDown">
<StackPanel Orientation="Horizontal" PreviewMouseDown="RunsetComboBoxItem_PreviewMouseDown">
<TextBlock Text="{Binding DisplayName}" PreviewMouseDown="RunsetComboBoxItem_PreviewMouseDown"/>
</StackPanel>
<StackPanel PreviewMouseDown="RunsetComboBoxItem_PreviewMouseDown">
<TextBlock Text="{Binding ExchangeMarketNames, StringFormat=🢒 {0}}" Visibility="{Binding ExchangeMarketNamesVisibility}" Margin="2,2,0,2" Foreground="LightGray" PreviewMouseDown="RunsetComboBoxItem_PreviewMouseDown" />
</StackPanel>
</StackPanel>
</CheckBox.Content>
</CheckBox>
<TextBlock Text="Select Items..." Visibility="{Binding DefaultItemVisibility}"/>
</Grid>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
The goal I'm trying to achieve is to have the ComboBox present a set of selectable ComboBoxItems. It should always display "Select Items" when closed:
And when opened I would like it to display the following:
When the highlighted area is clicked it should check the checkbox without closing the combobox. I have managed to get most of the behaviour I want by hacking the Visibility property to hide the checkbox in the "Select Items..." ComboBoxItem. Together with capturing the PreviewMouseDown event:
private void RunsetComboBoxItem_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
var checkBox = sender as CheckBox;
if(checkBox != null)
{
checkBox.IsChecked = !checkBox.IsChecked;
e.Handled = true;
}
}
This is almost working perfectly, but there are two issues that I can't resolve:
If I click on the border between the ComboBoxItems in the dropdown it will select that ComboBoxItem. I want it to never select any of them. I have managed to work around for clicks inside the highlighted area by capturing the preview mouse down event on the Grid in the and marking it handled. Unfortunately in the border this doesn't get triggered and the SelectedItemChanged event gets triggered on the ComboBox. This causes the selected item to change (as mentioned, I want the ComboBox to always display the "Select Items..." ComboBoxItem.
The "Select Items..." is shown twice when the combo box is expaned. I would like it to show just once.
I have managed to get most of the behaviour I want by hacking the Visibility property to hide the checkbox in the "Select Items..." ComboBoxItem together with capturing the PreviewMouseDown event.
I have read through many stack overflow posts about this, and I have not found a way of doing this. I tried capturing the SelectionChange and marking it handled but it closed the combobox anyway, and there is no PreviewSelectionChange event. When an item is selected I'd like the combobox to stay open.
Is there any way I can achieve this? Please let me know if there's any more information I can add to clarify my problem. Thanks!

set SelectionChanged in ListView Clickmode = "pressed" in uwp

I have a ListView and i want ListView to be selected when Mouse pressed. (Like ClickMode property of Buttons). is there any solution ?
I tried to put button in ListView template and change its ClickMode property
The SelectionChanged is triggered when mouse released which is by default. It seems like we cannot change it. So we can put button in ListView item template and change its click mode as what you thought about, or register a PointerPressed event for the container inside item template which will be triggered when mouse pressed not released.
but i couldn't access object that is clicked in the ListView
To access which item is clicked you still can use property like SelectedItem of ListView to get the selected item. For example:
XAML Code
<ListView Name="CategoryLIstView" Grid.Row="1" ItemsSource="{x:Bind categories}" HorizontalAlignment="Center" Margin="10" VerticalAlignment="Top" IsItemClickEnabled="True" SelectionChanged="CategoryLIstView_SelectionChanged" ItemClick="CategoryLIstView_ItemClick" PointerPressed="CategoryLIstView_PointerPressed">
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:Category">
<StackPanel Margin="0" PointerPressed="StackPanel_PointerPressed">
<StackPanel Orientation="Vertical" >
<TextBlock Text="{x:Bind Name}" Foreground="Blue" FontWeight="Bold" FontFamily="Yu Gothic" FontSize="17"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Code behind:
private async void StackPanel_PointerPressed(object sender, PointerRoutedEventArgs e)
{
await new Windows.UI.Popups.MessageDialog("point press").ShowAsync();
System.Diagnostics.Debug.WriteLine(CategoryLIstView.SelectedIndex);
}

SlectedItem when I click in a textbox or button in Datatemplate of a listview

I have a textbox and a button in a datatemplate as follows:
<DataTemplate x:Key="MyTemp1" x:DataType="data:Test">
<StackPanel Width="400">
<TextBox x:Name="tBoxName" Text="{Binding PhoneNumebr, Mode=TwoWay}" />
<Button x:Name="myButton" Content="textbutton" Click="myButtonButton_Click"/>
</StackPanel>
</DataTemplate>
and here my listView:
<ListView x:Name="myList" ItemTemplate="{StaticResource MyTemp1}"
SelectionChanged="myList_SelectionChanged"
IsItemClickEnabled="False"/>
for a listView in an UWP app, so I need a solution, that when I select the textbox or button, then selecteditem is accrued. In fact selectionchanged event is not fired when textbox or button is selected. is there any way to get selected item when textbox or button is selected? thanks
My problem has been solved as MikeBMcL explaind at this ilink:
https://social.msdn.microsoft.com/Forums/windowsapps/en-US/a5191023-fcdd-4e94-924e-6dee8e888267/uwp-xaml-button-on-list-item?forum=wpdevelop

How to show Popup/Flyout at clicked item in ListView/GridView in Windows Store App

I am working on a Windows Store App and would like to show some additional information about an Item that was clicked in ListView or GridView. This information should be shown in a Popup or Flyout (hast do be definded in C#, not in XAML) next to the clicked item.
The Problem is, that the ItemClick event handler gives no information about the clicked visual item but only about the data item. Thus I have no information about where to show the Flyout or Popup on screen.
Use attached Flyout:
<DataTemplate x:Key="ListItemTemplate">
<Grid RightTapped="ListRightTapped" Tapped="ListTapped" Background="Transparent">
<Grid>
...
</Grid>
<FlyoutBase.AttachedFlyout>
<Flyout Closed="listFlyout_Closed">
<StackPanel>
...
</StackPanel>
</Flyout>
</FlyoutBase.AttachedFlyout>
</Grid>
</DataTemplate>
And the code:
private void ListRightTapped( object sender, RightTappedRoutedEventArgs e )
{
FlyoutBase.ShowAttachedFlyout( sender as FrameworkElement );
}
I've created a solution that works just like the old Windows Phone Toolkit ContextMenuService. The MenuFlyoutService. You can find the source on my blog. Using the service removes the need to subscribe to event handlers wherever you want to show the menu.
Your DataTemplate would look something like:
<StackPanel>
<local:MenuFlyoutService.MenuFlyout>
<MenuFlyout>
<!-- using the Click event -->
<MenuFlyoutItem Text="reply" Click="OnReplyClicked"/>
<!-- using commanding to DataContext of MenuItem -->
<MenuFlyoutItem Text="retweet" Command="{Binding RetweetCommand}"/>
<!-- using commanding to DataContext of parent list -->
<MenuFlyoutItem Text="favorite"
Command="{Binding DataContext.FavoriteCommand,
ElementName=TweetList}"
CommandParameter="{Binding}"/>
</MenuFlyout>
</local:MenuFlyoutService.MenuFlyout>
<!-- content for template goes here -->
</StackPanel>
All you need to do is get DataContext:
If You have list with items:
MyList.ItemSource = new List<Item>();
And in XAML:
<ListView x:Name="MyList">
<ListView.ItemTemplate>
<DataTemplate>
<Stackpanel>
<TextBox Text="{Binding Name}" />
<Button Content="Add sth" Click="AddClick" />
</Stackpanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
And in CodeBehind to access Item while click on the button on the list:
private void AddClick(sender, args){
var senderButton= (Button) sender;
var item = (Item) sender.DataContext; //Item form the list
}
var item is whar you are looking for

DataGrid Cell with text and button

In a cell of a DataGrid there is a "add" button and then a textblock show quantity. When the user clicks on the "add" button it adds one to the quantity. I am having a hard time figuring out how to create the textblock. Here is my cell;
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Button Content="+" Click="addQTYButton_Click"/>
<TextBlock Text="{Binding qty}"/>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
The best solution would be not to use the Click event and the code-behind.
Use a command instead and in your ViewModel change the string the TextBlock is bound to when the command is invoked...
If you insist using the event and the code-behind, just name the TextBlock and it will be available to you in the event handler to manipulate it any way you like...

Categories