Finding Listbox Index of ListBoxItem (ItemsTemplate to specify Visual COntent) - c#

How do you find the index of a ListBoxItem if it is set within a DataTemplate as a Textbox control? Here is the WPF:
<ListBox Name="ScriptEditor" Margin="10" Height="291" ItemsSource="{Binding Path=Script}" SelectionChanged="ScriptEditor_SelectionChanged_1" >
<ListBox.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding Path=Command}"PreviewMouseDoubleClick="Command_DoubleClick" GotFocus="ScriptEditor_GotFocus" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
When I gain focus of the textbox (text is bound to an observableCollection), I cannot simply use the SelectionChanged Event on the ListBox. I would like to know how I can determine the index of the textbox I have gained focus in.
Thanks

You could bind the AlternationCount to the Script.Count then add the AlternationIndex from the ItemsControl(ListBox) to the Textbox Tag property so you can access from your GotFocus event handler.
Example:
<ListBox Name="ScriptEditor" Margin="10" Height="291" ItemsSource="{Binding Script}" AlternationCount="{Binding Script.Count}" >
<ListBox.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding ., Mode=OneWay}" GotFocus="ScriptEditor_GotFocus"
Tag="{Binding Path=(ItemsControl.AlternationIndex), Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
private void ScriptEditor_GotFocus(object sender, RoutedEventArgs e)
{
int index = (int)(sender as TextBox).Tag;
}

Related

Lost focus event is not occured for ListBox.ItemTemplate during SelectedItem chaged event of the hosting Listbox

there is the following definition of a listbox
<ListBox ItemsSource ="{Binding MyItems}" SelectedValue ="{Binding SelectedItem}">
<ListBox.ItemTemplate>
<DataTemplate>
<WrapPanel >
<CheckBox IsChecked ="{Binding IsSelected, Mode=TwoWay}"/>
<TextBox Text ="{Binding Description, Mode = TwoWay}" LostFocus="OnLostFocus"/>
</WrapPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
the problem that I have faced that LostFocus event is not appeared when a selected index of the ListBoxChanged (for example by pressing arrow up on a selected item), but occures when I do mouse clicks on the other ListboxItems.
How to make it work consitantly?

Autocomplete causes text to scroll to right

Autocomplete on my editable combobox works fine for short items.
However, if the selected string is too wide and does not fit in the combobox, it scrolls horizontally to the right, presumably as a result of the autocomplete feature selecting the remainder of the string.
This hides the current location of the point at which the user is typing.
How do I get it to keep the position of the caret visible to the user?
<ComboBox x:Name="comboBoxCustomer"
ItemsSource="{Binding Source={StaticResource customerViewSource}}"
TextSearch.TextPath="CustomerDisplay"
SelectedValue="{Binding CustomerID, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}"
SelectedValuePath="ID"
SelectionChanged="comboBoxCustomer_SelectionChanged"
StaysOpenOnEdit="True"
IsEditable="True" >
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding CustomerDisplay}" Foreground="{Binding ActiveColour}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Use ScrollToHome method on textbox of combobox.
private void comboBoxCustomer_KeyUp(object sender, KeyEventArgs e)
{
TextBox tb = (TextBox)comboBoxCustomer.Template.FindName("PART_EditableTextBox", comboBoxCustomer);
tb.ScrollToHome();
}
You should try this.
<ComboBox x:Name="comboBoxCustomer"
ItemsSource="{Binding Source={StaticResource customerViewSource}}"
TextSearch.TextPath="CustomerDisplay"
SelectedValue="{Binding CustomerID, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}"
SelectedValuePath="ID"
SelectionChanged="comboBoxCustomer_SelectionChanged"
StaysOpenOnEdit="True"
IsEditable="True" >
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding CustomerDisplay}" Foreground="{Binding ActiveColour}" **TextAlignment="Left"** />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>

DataGridCellEditEnding event is not firing when I am changing dropdown inside my datagrid in WPF

I am using the following code to use a ComboBox inside my DataGridTemplateColumn:
<DataGridTemplateColumn Header="MyHeader" Width="50">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Width="Auto" Text="{Binding Path=MyVal}" ToolTip="{Binding MyDisplayName}"></TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox Width="50" Height="17" ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type UserControl}},Path=DataContext.MyList}"
SelectedValuePath="MyValPath" SelectedValue="{Binding MySelectedVal}" SelectedItem="{Binding MyObject}" DisplayMemberPath="MyDisplayName"
FontSize="12" >
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
CellTemplate is for showing my text (custom text for selected value) and CellEditingTemplate contains my ComboBox which has the actual list.
When I select a value from my drop-down, I have to click on another part of the data grid to get DataGridDiagnosticCellEditEnding fired.
I want to get it fired as soon as I select a value or change a value from my ComboBox.
I tried adding the following code, but it didn't work:
<ComboBox Width="50" Height="17" ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type UserControl}},Path=DataContext.MyList}"
SelectedValuePath="MyValPath" SelectedValue="{Binding MySelectedVal}" SelectedItem="{Binding MyObject, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" DisplayMemberPath="MyDisplayName" FontSize="12" >
Also I tried adding IsSynchronizedWithCurrentItem="True".
I gave a try to your code, and ve got a fix :
On the ComboBox of the DataGrid Column, subscribe to the closing event
Implement the event Handler and raise a routed Event.
CommitEditCommand belongs to the DataGrid class :
private void ComboBoxDropDownClosed(object sender, EventArgs e)
{
DataGrid.CommitEditCommand.Execute(datagrid1,datagrid1);
}
From there you fall in the DataGrid.CellEditting breakpoint
Here is the working solution : http://1drv.ms/1LFB5Gc
Regards

How can i bind a button in listviewitem to a Command in ViewModel in Winrt

I have a NavigateToAccountsCommand RelayCommand property in the ViewModel. When I bind the same to a button on the page anywhere outside the ListView the command binding is working. However as soon as I move this to a ListView's DataTemplate its not working.
I have tried changing the binding from NavigateToAccountsCommand to DataContext.NavigateToAccountsCommand still not working.
Appreciate your help...
<Page
x:Class="FinancePRO.App.Views.AccountsView"
DataContext="{Binding AccountsViewModel, Source={StaticResource MainViewModelLocator}}"
mc:Ignorable="d">
<Grid>
<!--**This one is working**-->
<Button Command="{Binding NavigateToAccountsCommand}" >
<!--**This one is not working**-->
<ListView ItemsSource="{Binding AllAccounts}" >
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel HorizontalAlignment="Stretch">
<TextBlock Text="{Binding AccountName}"/>
<Button Command="{Binding NavigateToAccountsCommand}">
</Button>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
When you are inside the DataTemplate of the ListView, your data context is the current item of the ListView's ItemsSource. As there is nothing called "NavigateToAccountsCommand" property within your AllAcounts' each individual element, binding isn't working.
To fix that, you will need to reference something from the outside of DataTemplate; following should work. It changes the binding to reference the root Grid's DataContext which should have the property NavigateToAccountsCommand accessible. To reference the grid, you have to add Name attribute, and then use ElementName binding.
<Grid Name="Root">
<!--**This one is working**-->
<Button Command="{Binding NavigateToAccountsCommand}" >
<!--**This one is not working**-->
<ListView ItemsSource="{Binding AllAccounts}" >
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel HorizontalAlignment="Stretch">
<TextBlock Text="{Binding AccountName}"/>
<Button Command"{Binding ElementName=Root, Path=DataContext.NavigateToAccountsCommand}">
</Button>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
You can use
<Button x:Name="cmdTabItemCloseButton"
Style="{StaticResource TabItemCloseButtonStyle}"
Grid.Column="1" Margin="15,0,0,0"
Command="{Binding RelativeSource=
{RelativeSource FindAncestor,
AncestorType={x:Type ListView}},
Path=DataContext.NavigateToAccountsCommand}"
CommandParameter="{Binding}"/>
I had a similar problem (Win RT) which I solved by just using:
<GridView
x:Name="itemGridView"
ItemClick="ItemView_ItemClick"
IsItemClickEnabled="True"/>
and then in the Page class:
private void ItemView_ItemClick(object sender, ItemClickEventArgs e)
{
//e is the object being clicked
}

Silverlight: Give focus to a parent ListBox item when clicking a child button

I have the following XAML code, having removed the styling and formatting tags:
<ListBox Name="ManageImageList">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<Image Name="ManageImageThumbnail" Source="{Binding ImageName}" />
<StackPanel Orientation="Vertical" >
<TextBlock Name="ManageImageUrl" Text="{Binding ImageName}" />
<TextBlock Name="ManageImageComment" Text="{Binding Comment}" />
</StackPanel>
<Button Name="ManageImageDelete" ClickMode="Press" Click="ManageImageDelete_Click" Content="X" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
The ListBox is bound to an ObservableCollection. I would like to give focus to the parent ListBox item when the button is clicked, making it the SelectedItem of the ListBox. How do I do this?
In the click event use:-
ManageImageList.SelectedItem = ((Button)sender).DataContext;

Categories