I have a TextBox inside a ListBoxItem which is disabled so I can drag and drop it in the ListBox.
Now once I double click it I want it to be Enabled so I can edit the text and when I'm done I want it do be disabled again to do drag and drop.
I have the MouseDoubleClick event on the ListBoxItem but I can't get access to the TextBox. Can anybody tell me how to achieve this.
at the moment textBox is not recognized in codebehind. seems like I don't get access to it the way I'm trying it.
XAML
<ListBox Name="Locations" Cursor="Hand" HorizontalAlignment="Left" Height="351" Margin="10,48,0,0" VerticalAlignment="Top" Width="285" ItemsSource="{Binding Locations}" IsSynchronizedWithCurrentItem="True" dd:DragDrop.IsDragSource="True"
dd:DragDrop.IsDropTarget="True" SelectedItem="{Binding SelectedItem}">
<ListBox.InputBindings>
<KeyBinding Key="Delete" Command="{Binding DeleteLocationCommand}" />
</ListBox.InputBindings>
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}" BasedOn="{StaticResource {x:Type ListBoxItem}}">
<EventSetter Event="MouseDoubleClick" Handler="ListBoxItem_MouseDoubleClick"/>
<EventSetter Event="LostFocus" Handler="ListBoxItem_LostFocus"/>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBox Name="textBox" Text="{Binding Path=Name}" IsHitTestVisible="False" Width="270" Background="Transparent" BorderThickness="0" Margin="2"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
In View
private void ListBoxItem_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
ListBoxItem item = sender as ListBoxItem;
textBox.IsReadOnly = false;
Locations.textBox.Background = Brushes.White;
textBox.SelectAll();
Cursor = Cursors.IBeam;
}
private void ListBoxItem_LostFocus(object sender, RoutedEventArgs e)
{
textBox.IsReadOnly = true;
}
you can use the ReadOnly property which will prevent the user from making any changes to the text:
texBox.ReadOnly = true;
and
private void changeText(object sender, EventArgs e)
{
(sender as TextBox).ReadOnly = false;
}
Related
<ListBox
x:Name="listBox"
SelectionChanged="listBox_SelectionChanged">
</ListBox>
void listBox_SelectionChanged(object sender, RoutedEventArgs e) {
// This method is only called when a selection is changed.
}
However, I need to call a function that executes even if the already selected item in the list box is clicked again (which would make it selected had it not already been).
I tried the Selected event handler but received this error in visual studio:
Error CS1061 'ListBox' does not contain a definition for 'Selected' and no accessible extension method 'Selected' accepting a first argument of type 'ListBox' could be found (are you missing a using directive or an assembly reference?)
Is there any other event I might be missing?
Thank you.
In .xaml (assume ListBox item is Grid)
<ListBox
x:Name="listBox"
SelectionChanged="listBox_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid PreviewMouseDown="listBox_OnPreviewMouseDown">
<!-- Content -->
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
In .xaml.cs (assume MyListItemType is the type of the item in ListBox)
private void listBox_OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
{
var clickedItem = (sender as FrameworkElement)?.DataContext as MyListItemType;
if (clickedItem != listBox.SelectedItem) return;
// same item is selected
// ..
}
private void listBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var clickedItem = (sender as FrameworkElement)?.DataContext as MyListItemType;
// new item is selected
// ..
}
First Example:
<UniformGrid>
<ListBox>
<ListBox.ItemsSource>
<sys:String>QWERTY</sys:String>
</ListBox.ItemsSource>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<EventSetter Event="PreviewMouseLeftButtonDown"
Handler="OnItemClick"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
<TextBlock x:Name="tBlock"/>
</UniformGrid>
</Window>
private int count = 0;
private void OnItemClick(object sender, MouseButtonEventArgs e)
{
count++;
tBlock.Text += $"{count}: {((ListBoxItem)sender).Content}{Environment.NewLine}";
}
Second Example:
<ListBox SelectionChanged="OnSelection"
HorizontalContentAlignment="Stretch">
<ListBox.ItemsSource>
<sys:String>QWERTY</sys:String>
</ListBox.ItemsSource>
<ListBox.ItemTemplate>
<DataTemplate DataType="{x:Type sys:Char}">
<Grid>
<TextBlock x:Name="PART_TBlock" Text="{Binding}"/>
<Button x:Name="PART_Btn" Content="{Binding}" Click="OnReselection"
BorderThickness="0" Background="Transparent"
HorizontalContentAlignment="Left"
Visibility="Collapsed"/>
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}"
Value="True">
<Setter TargetName="PART_TBlock" Property="Visibility" Value="Collapsed"/>
<Setter TargetName="PART_Btn" Property="Visibility" Value="Visible"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<TextBlock x:Name="tBlockReselection"/>
</UniformGrid>
</Window>
private void OnSelection(object sender, SelectionChangedEventArgs e)
{
tBlockReselection.Text += $"Selected: {((ListBox)sender).SelectedItem}{Environment.NewLine}";
}
private void OnReselection(object sender, RoutedEventArgs e)
{
tBlockReselection.Text += $"Reselected: {((Button)sender).Content}{Environment.NewLine}";
}
Third Example:
<ItemsControl HorizontalContentAlignment="Stretch">
<ItemsControl.ItemsSource>
<sys:String>QWERTY</sys:String>
</ItemsControl.ItemsSource>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type sys:Char}">
<Button Content="{Binding}" Click="OnClickselection"
HorizontalContentAlignment="Left"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<TextBlock x:Name="tBlockClickSelection"/>
</UniformGrid>
</Window>
private void OnClickselection(object sender, RoutedEventArgs e)
{
tBlockClickSelection.Text += $"ClickSelection: {((Button)sender).Content}{Environment.NewLine}";
}
Is there any way to find out witch Item number is under the pointer on GridView? I like to show short information about the item under the mouse without selecting the item by any click.
You could handle the PointerEntered and PointerExited events for the root element in your ItemTemplate.
XAML:
<GridView>
<x:Int32>1</x:Int32>
<x:Int32>2</x:Int32>
<x:Int32>3</x:Int32>
<GridView.ItemContainerStyle>
<Style TargetType="GridViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
</Style>
</GridView.ItemContainerStyle>
<GridView.ItemTemplate>
<DataTemplate>
<Grid PointerEntered="TextBlock_PointerEntered"
PointerExited="TextBlock_PointerExited"
Background="Transparent">
<TextBlock Text="{Binding}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
<TextBlock x:Name="tb" />
Code:
private void TextBlock_PointerEntered(object sender, PointerRoutedEventArgs e)
{
Panel root = sender as Panel;
var dataObject = root.DataContext;
tb.Text = dataObject.ToString(); //displays the currently pointed number in "tb"
}
private void TextBlock_PointerExited(object sender, PointerRoutedEventArgs e)
{
tb.Text = string.Empty;
}
In Windows Universal app, I have a pivot table which every tab content have gridview, gridview items are multi select mode,
What I want that if any one item once checked (selected), then it unable to unselect(uncheck)
<Grid DataContext="{Binding Path=Value}">
<GridView x:Name="categoryItemsGV"
Margin="5,5,0,0"
SizeChanged="categoryItemsGV_SizeChanged"
IsItemClickEnabled="True"
ItemClick="categoryItemsGV_ItemClick"
SelectionMode="Single"
ItemsSource="{Binding}">
<GridView.ItemContainerStyle>
<Style TargetType="GridViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<!--<Setter Property="VerticalContentAlignment" Value="Center"/>-->
</Style>
</GridView.ItemContainerStyle>
<GridView.ItemTemplate>
<DataTemplate>
<Grid Width="195" Height="43" Margin="3">
<StackPanel Width="193" Height="40" Background="Gray" Opacity="0.5" HorizontalAlignment="Right" VerticalAlignment="Bottom" />
<StackPanel Orientation="Horizontal" Width="193" Height="40" Padding="7,7,0,0" Background="#FDFCC2" HorizontalAlignment="Left" VerticalAlignment="Top">
<TextBlock Text="{Binding ProductOptionLineName}" FontSize="18" MaxLines="1" TextTrimming="CharacterEllipsis" Visibility="{Binding Converter={StaticResource langToVisibilityConverter}, ConverterParameter='CH', Mode=OneWay}">
</TextBlock>
<TextBlock Text="{Binding ProductOptionLineNameEn}" FontSize="18" MaxLines="1" TextTrimming="CharacterEllipsis" Visibility="{Binding Converter={StaticResource langToVisibilityConverter}, ConverterParameter='EN', Mode=OneWay}"/>
<TextBlock Text="{Binding ExtraPriceString}" FontSize="18" Margin="2,0,0,0"></TextBlock>
</StackPanel>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</Grid>
private async void categoryItemsGV_ItemClick(object sender, ItemClickEventArgs e)
{
var item = e.ClickedItem as ProductOptionLineModel;
}
We can use the SelectRange(ItemIndexRange) method to selects a block of items described by the ItemIndexRange.
When you call SelectRange(ItemIndexRange), all items in the specified range are selected, regardless of their original selection state. You can select all items in a collection by using an ItemIndexRange with a FirstIndex value of 0 and a Length value equal to the number of items in the collection.
For more info, see Remarks of the SelectRange(ItemIndexRange).
We can use the ItemClick to get which item is be clicked. Then we can add the SelectionChanged event and set the number of the clicked item to the SelectRange method.
For example:
private int number;
private void categoryItemsGV_ItemClick(object sender, ItemClickEventArgs e)
{
var item = e.ClickedItem as ProductOptionLineModel;
number = ProductOptionLineModels.IndexOf(item);
}
private void categoryItemsGV_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
categoryItemsGV.SelectRange(new ItemIndexRange(number, 1));
}
If we want to keep item selected as it was already selected, use below approach.
private async void categoryItemsGV_ItemClick(object sender, ItemClickEventArgs e)
{
var item = e.ClickedItem as ProductOptionLineModel;
GridView gv = sender as GridView;
gv.SelectedItems.Remove(item);
}
and if we want to keep item deselect on click (prevent deselected) for validation purpose. used below approach.
private async void categoryItemsGV_ItemClick(object sender, ItemClickEventArgs e)
{
var item = e.ClickedItem as ProductOptionLineModel;
await _viewModel.DialogService("FirstRequireMinOption", "", true);
GridView gv = sender as GridView;
gv.SelectedItems.Add(item);
}
i want to select a listviewitem, where a button was clicked.
Here is my Listview with 2 llistviewitems
I click the X-Button and want to delete these item out of the list. How i get that item?
I have these code:
private void Delete_Click(object sender, RoutedEventArgs e)
{
var item = sender as ListViewItem;
var obj = item.Content as object;
List.Remove(obj);
}
Edit: The Binding of the ListView
<ListView x:Name="listview">
<ListView.ItemTemplate>
<DataTemplate>
<WrapPanel>
<TextBlock Text="Bild "/>
<TextBlock Text="{Binding Title}"/>
<Button x:Name="Change" Content="Change" Margin="250,0,0,0" Click="Change_Click"/>
<Button x:Name="Delete" Content="X" Margin="10,0,0,0" Click="Delete_Click"/>
</WrapPanel>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Height" Value="50"/>
<EventSetter Event="PreviewMouseLeftButtonDown" Handler="lvSeriesItem_PreviewMouseLeftButtonDown"/>
</Style>
</ListView.ItemContainerStyle>
</ListView>
please use this instead.The control that raised the event is not the listbox but the button.The button as a datacontext of your collection model object. so this should workd
private void Delete_Click(object sender, RoutedEventArgs e)
{
var button= sender as Button;
var obj =(YourModelHere)button.DataContext;
List.Remove(obj);
}
sender will be the Button, your data item will be the DataContext of said button.
My problem is that I need the Value of a Label in a Template as a string. Its a Template for a ListBoxItem with a CheckBox and a Label. When the box get checked I need the Value of the Label as a string variable in the code.
ListBox
<ListBox HorizontalAlignment="Left" Height="196" Margin="10,24,0,0"
VerticalAlignment="Top" Width="155" BorderBrush="#FF7799BB"
Name="ListBoxTblColumns" DataContextChanged="TableColumns_DataContextChanged"
ItemsSource="{Binding Columns}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox Name="columnSelectBox" Margin="0,7,4,0" Checked="columnSelectBox_Checked" Unchecked="columnSelectBox_Unchecked"/>
<Label Name="lblColName" Content="{Binding}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Focusable" Value="False"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
And in this event I want to get the value from lblColName:
public void columnSelectBox_Checked(object sender, RoutedEventArgs e)
{
string colName = ...;
}
Ideas?