Let me try again...here is the XAML. You can see the CollectionViewSource, the Grid that uses it as a DataContext, the ListView, and the Delete button. What is happening is that when i click on a row in the ListView (and the Style trigger fires to select the ListViewItem) the row is selected. When i click the Delete button the onclick fires but the CurrentPosition property is set to -1. What is preventing the CurrentPosition property from being updated.
XAML
<Window x:Class="PretzelsUI.Admin.Ovens"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title=""
Height="344"
Width="474"
mc:Ignorable="d"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:my="clr-namespace:Pretzels.Model;assembly=Pretzels.Model"
ResizeMode="NoResize"
WindowStartupLocation="CenterOwner"
Background="{StaticResource WindowGradient}"
Loaded="Window_Loaded">
<Window.Resources>
<CollectionViewSource x:Key="ovenViewSource" d:DesignSource="{d:DesignInstance my:Oven, CreateList=True}" />
</Window.Resources>
<Grid DataContext="{StaticResource ovenViewSource}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border Grid.Row="0" BorderBrush="{StaticResource formTitleBorderBrush}" BorderThickness="2" Name="border1" CornerRadius="30" Padding="7" Background="{StaticResource formTitleBackgroundBrush}" VerticalAlignment="Center" Margin="11">
<TextBlock Name="textBlock1" Text="Ovens" FontSize="18" FontWeight="Bold" Foreground="{StaticResource formTitleForegroundBrush}" />
</Border>
<ListView IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding}" Name="ovenListView" SelectionMode="Single" Height="177" Grid.Row="1" TabIndex="2" Margin="5,5,5,0">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Control.HorizontalContentAlignment" Value="Stretch" />
<Setter Property="Control.VerticalContentAlignment" Value="Stretch" />
<!--<Style.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="IsSelected" Value="True" />
</Trigger>
</Style.Triggers>-->
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView>
<GridViewColumn x:Name="nameColumn" Header="Name" Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Margin="-6,-1" Text="{Binding Path=OvenName, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true, UpdateSourceTrigger=PropertyChanged}" Width="Auto" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn x:Name="descriptionColumn" Header="Description" Width="300">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Margin="-6,-1" Text="{Binding Path=OvenDescription, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" Width="Auto" MaxLength="100"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
<StackPanel Grid.Row="2" Name="stackPanel2" Margin="0,30,0,0" Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center">
<Button Content="New" Height="23" Margin="2,0,2,0" TabIndex="3" Name="btnAdd" Width="75" Click="btnInsrt_Click" />
<Button Content="Save" Height="23" Margin="2,0,2,0" TabIndex="4" Name="btnSave" Width="75" Click="btnSave_Click" />
<Button Content="Delete" Height="23" Margin="2,0,2,0" TabIndex="5" Name="btndelete" Width="75" Click="btndelete_Click" />
</StackPanel>
</Grid>
C#
public partial class Ovens : Window
{
private PretzelEntities dbcontext = new PretzelEntities();
//private OvenCollection EntityData;
private CollectionViewSource ViewSource;
private BindingListCollectionView OvenView;
public Ovens()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
ViewSource = (CollectionViewSource)this.FindResource("ovenViewSource");
ViewSource.Source = from s in dbcontext.Ovens select s;
OvenView = (BindingListCollectionView)(ViewSource.View);
}
private void btndelete_Click(object sender, RoutedEventArgs e)
{
if (OvenView.CurrentPosition > -1)
{
if (MessageBox.Show("Do you really want to delete this Oven?", "Delete Confirmation", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
this.OvenView.RemoveAt(this.OvenView.CurrentPosition);
}
}
else
{
MessageBox.Show("Nothing to Delete.", "Error", MessageBoxButton.OK);
}
}
enter code here
I think what is happening is that when the trigger fires the CurrentItem/CurrentPosition of the ListCollectionView is not being properly updated. I am not sure to go about doing this (although I know the methods available) manually when i click on a textbox in one of the rows. Not sure what to do so i may just manually located the selected ListViewItem using the VisualTreeHelper.
I finally gave up on the style trigger and just handled the GotFocus event for the textbox/combobox inside the ListView rows. In side the handler i was able to get the ListViewItem and set the IsSelected to true. Works like a champ.
IMO, it's better to set this all up in code like so:
You can call that method in you Window_Loaded, eliminate the other code in Window_Loaded, and then eliminate the bindings, since you are doing it all in code already. It would really be better to set this all up without any of this code in the view (MVVM), but that goes beyond the context of this question.
Did some testing and the problem is with the style trigger.
I am using the style trigger to select the ListViewItem when i click on anything inside the ListViewItem (i.e. TextBox/ComboBox). When this trigger is in place the row selects if i select a TextBox but the CurrentPosition of the ListCollectionView is always -1. If i remove the trigger and actually select the row itself (click outside the textbox) boom the CurrentPosition is set properly. My question is why...do i need to manually set the CurrentPosition. Any help appreciated.