I find the problem I have very strange.
I have a WPF application using MVVM pattern.
I retrieve data from my database using Linq-to-SQL and display the Description field data in a ListBox using binding.
It works, but not completely. For some reason the last record's does not display. I have verified it is fetched from the database. It cannot be selected; its not there at all.
The only way to get the record to appear is by setting focus to the ListBox and either scrolling the mouse scroller or actually moving down using the keyboard to past the last record (which is supposed to be the second last record). Once you do that, the record appears.
Another way to get the record to show up is update any of the records in the ListBox. I have a TextBox bound in two-way mode to the SelectedItem of the ListBox, So when I select an item, change the text in the TextBox and click the Update button, it calls the Command to do the database update, which works fine, but then also the missing record of the last record shows up.
Is there a rendering problem with ListBox and ListView, because I have tried both? Why does it seem like the ListBox needs to be "redrawn" before the last items appears?
CategoryModel.cs
public class CategoryModel
{
public int CategoryID { get; set; }
public string Description { get; set; }
public List<CategoryModel> categories = new List<CategoryModel>();
readonly SalesLinkerDataContext _dbContext = new SalesLinkerDataContext();
public void GetCategories()
{
categories.Clear();
var result = _dbContext.tblSalesCategories.ToList();
foreach (var item in result)
{
categories.Add(new CategoryModel
{
CategoryID = item.CategoryID,
Description = item.Description.Trim()
});
}
}
internal void Update(CategoryModel cm)
{
try
{
var category = (from a in _dbContext.tblSalesCategories
where a.CategoryID == cm.CategoryID
select a).FirstOrDefault();
if (category != null)
{
category.Description = cm.Description;
_dbContext.SubmitChanges();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
CategoriesViewModel.cs
public class CategoriesViewModel : ViewModelBase, IPageViewModel
{
public CategoryModel Categories = new CategoryModel();
private DelegateCommand _getCategoriesCommand;
private DelegateCommand _updateCategoryCommand;
/// <summary>
/// Describes the name that will be used for the menu option
/// </summary>
public string Name
{
get { return "Manage Categories"; }
}
public string Description
{
get { return Categories.Description; }
set
{
Categories.Description = value;
OnPropertyChanged("Description");
}
}
public List<CategoryModel> ReceivedCategories
{
get { return Categories.categories; }
set
{
Categories.categories = value;
OnPropertyChanged("ReceivedCategories");
}
}
public ICommand GetCategoriesCommand
{
get
{
if (_getCategoriesCommand == null)
{
_getCategoriesCommand = new DelegateCommand(GetCategories, CanGetCategories);
}
return _getCategoriesCommand;
}
}
private bool CanGetCategories()
{
return true;
}
private void GetCategories()
{
Categories.GetCategories();
ReceivedCategories = Categories.categories;
}
public ICommand UpdateCategoryCommand
{
get
{
if (_updateCategoryCommand == null)
{
_updateCategoryCommand = new DelegateCommand(UpdateCategory, CanUpdateCategory);
}
return _updateCategoryCommand;
}
}
private bool CanUpdateCategory()
{
return true;
}
private void UpdateCategory()
{
Categories.Update(Categories);
}
}
CategoriesView.xaml
<UserControl x:Class="SalesLinker.CategoriesView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="600" Background="White" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding GetCategoriesCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="45"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="250"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0" Margin="20,0,0,0" FontSize="20" HorizontalAlignment="Center" Content="Categories"/>
<ListView x:Name="LstCategories" ItemsSource="{Binding ReceivedCategories, Mode=TwoWay}" Grid.Column="0" Grid.Row="1"
VerticalAlignment="Stretch"
Background="LightGray"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
SelectionChanged="LstCategories_OnSelectionChanged">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" VerticalAlignment="Stretch" >
<TextBlock Text="{Binding Description }"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Button Command="{Binding AddCategoryCommand}" Grid.Column="1" Grid.Row="1" VerticalAlignment="Top" Height="50" Width="50" Margin="0,20,0,0" Background="Transparent" BorderThickness="0" BorderBrush="Transparent" >
<Image Source="/Images/Plus.png"/>
</Button>
<Button Command="{Binding RemoveCategoryCommand}" Grid.Column="1" Grid.Row="1" VerticalAlignment="Top" Height="50" Width="50" Margin="0,75,0,0" Background="Transparent" BorderThickness="0">
<Image Source="/Images/Minus.png"/>
</Button>
<Grid Grid.Row="1" Grid.Column="2">
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="75"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Row="0" Grid.Column="0" Content="Description:"/>
<TextBox DataContext="CategoryModel" Grid.Row="0" Grid.Column="1" Width="250" Height="Auto" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10,0,0,0"
Text="{Binding SelectedItem.Description, ElementName=LstCategories}"/>
<Button Command="{Binding UpdateCategoryCommand}"
Grid.Row="1" Grid.Column="1" HorizontalAlignment="Left" Margin="10,0,0,0" Height="20" Width="120" Content="Update Description"/>
</Grid>
</Grid>
I am very new to MVVM so hopefully I am just not seeing something simple.